<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>

<link href='https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; }
.mac-os-11 { --title-bar-height: 28px; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4, h5 { white-space: pre-wrap; }
body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; overflow-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
.typora-export .task-list-item input { pointer-events: none; }
@media screen and (max-width: 500px) {
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  #write { padding-left: 20px; padding-right: 20px; }
}
#write li > figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
button, input, select, textarea { color: inherit; font: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px; }
thead, tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
svg { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li blockquote { margin: 1rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
  body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
  #write { margin-top: 0px; border-color: transparent !important; padding-top: 0px !important; padding-bottom: 0px !important; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  .typora-export #write { break-after: avoid; }
  .typora-export #write::after { height: 0px; }
  .is-mac table { break-inside: avoid; }
  #write > p:nth-child(1) { margin-top: 0px; }
  .typora-export-show-outline .typora-export-sidebar { display: none; }
  figure { overflow-x: visible; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
.MathJax_ref { fill: currentcolor; }
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.reversefootnote { font-family: ui-monospace, sans-serif; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.6; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }
mark { background: rgb(255, 255, 0); color: rgb(0, 0, 0); }
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
.md-expand mark .md-meta { opacity: 0.3 !important; }
mark .md-meta { color: rgb(0, 0, 0); }
@media print {
  .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
}
.md-diagram-panel .messageText { stroke: none !important; }
.md-diagram-panel .start-state { fill: var(--node-fill); }
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
.md-fences.md-fences-math { font-size: 1em; }
.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }
.md-fences-advanced:not(.md-focus) { background: inherit; }
.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }
.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }
.typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; }
.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }
@media screen and (max-width: 1024px) {
  .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }
}
@media screen and (max-width: 800px) {
  .typora-export-sidebar { display: none; }
}
.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; overflow-wrap: anywhere; }
.outline-content ul { margin-top: 0px; margin-bottom: 0px; }
.outline-content strong { font-weight: 400; }
.outline-expander { width: 1rem; height: 1.42857rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }
.outline-expander::before { content: ""; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }
.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }
.outline-expander:hover::before { content: ""; }
.outline-h1 > .outline-item { padding-left: 0px; }
.outline-h2 > .outline-item { padding-left: 1em; }
.outline-h3 > .outline-item { padding-left: 2em; }
.outline-h4 > .outline-item { padding-left: 3em; }
.outline-h5 > .outline-item { padding-left: 4em; }
.outline-h6 > .outline-item { padding-left: 5em; }
.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }
.outline-label:hover { text-decoration: underline; }
.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }
.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left: 28px solid transparent; border-right: 28px solid transparent; }
.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }
.outline-item-open > .outline-item > .outline-expander::before { content: ""; }
.outline-children { display: none; }
.info-panel-tab-wrapper { display: none; }
.outline-item-open > .outline-children { display: block; }
.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }
.typora-export .outline-item:hover { margin-right: -8px; border-right: 8px solid transparent; }
.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }
.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: "−"; }
.typora-export-collapse-outline .outline-children { display: none; }
.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }
.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }
.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }
.md-inline-math-container mjx-container { zoom: 0.95; }
mjx-container { break-inside: avoid; }
.md-alert.md-alert-note { border-left-color: rgb(9, 105, 218); }
.md-alert.md-alert-important { border-left-color: rgb(130, 80, 223); }
.md-alert.md-alert-warning { border-left-color: rgb(154, 103, 0); }
.md-alert.md-alert-tip { border-left-color: rgb(31, 136, 61); }
.md-alert.md-alert-caution { border-left-color: rgb(207, 34, 46); }
.md-alert { padding: 0px 1em; margin-bottom: 16px; color: inherit; border-left: 0.25em solid rgb(0, 0, 0); }
.md-alert-text-note { color: rgb(9, 105, 218); }
.md-alert-text-important { color: rgb(130, 80, 223); }
.md-alert-text-warning { color: rgb(154, 103, 0); }
.md-alert-text-tip { color: rgb(31, 136, 61); }
.md-alert-text-caution { color: rgb(207, 34, 46); }
.md-alert-text { font-size: 0.9rem; font-weight: 700; }
.md-alert-text svg { fill: currentcolor; position: relative; top: 0.125em; margin-right: 1ch; overflow: visible; }
.md-alert-text-container::after { content: attr(data-text); text-transform: capitalize; pointer-events: none; margin-right: 1ch; }


.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
span.cm-underlined { text-decoration: underline; }
span.cm-strikethrough { text-decoration: line-through; }
.cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); }
.cm-tw-deleted { text-decoration: line-through; }
.cm-tw-header5 { font-weight: 700; }
.cm-tw-listitem:first-child { padding-left: 10px; }
.cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; }
.cm-tw-underline { text-decoration: underline; }
@media print {
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}


:root {
    --side-bar-bg-color: #fafafa;
    --control-text-color: #777;
}

@include-when-export url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);

/* open-sans-regular - latin-ext_latin */
  /* open-sans-italic - latin-ext_latin */
    /* open-sans-700 - latin-ext_latin */
    /* open-sans-700italic - latin-ext_latin */
  html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
}

body {
    font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif;
    color: rgb(51, 51, 51);
    line-height: 1.6;
}

#write {
    max-width: 860px;
  	margin: 0 auto;
  	padding: 30px;
    padding-bottom: 100px;
}

@media only screen and (min-width: 1400px) {
	#write {
		max-width: 1024px;
	}
}

@media only screen and (min-width: 1800px) {
	#write {
		max-width: 1200px;
	}
}

#write > ul:first-child,
#write > ol:first-child{
    margin-top: 30px;
}

a {
    color: #4183C4;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    position: relative;
    margin-top: 1rem;
    margin-bottom: 1rem;
    font-weight: bold;
    line-height: 1.4;
    cursor: text;
}
h1:hover a.anchor,
h2:hover a.anchor,
h3:hover a.anchor,
h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
    text-decoration: none;
}
h1 tt,
h1 code {
    font-size: inherit;
}
h2 tt,
h2 code {
    font-size: inherit;
}
h3 tt,
h3 code {
    font-size: inherit;
}
h4 tt,
h4 code {
    font-size: inherit;
}
h5 tt,
h5 code {
    font-size: inherit;
}
h6 tt,
h6 code {
    font-size: inherit;
}
h1 {
    font-size: 2.25em;
    line-height: 1.2;
    border-bottom: 1px solid #eee;
}
h2 {
    font-size: 1.75em;
    line-height: 1.225;
    border-bottom: 1px solid #eee;
}

/*@media print {
    .typora-export h1,
    .typora-export h2 {
        border-bottom: none;
        padding-bottom: initial;
    }

    .typora-export h1::after,
    .typora-export h2::after {
        content: "";
        display: block;
        height: 100px;
        margin-top: -96px;
        border-top: 1px solid #eee;
    }
}*/

h3 {
    font-size: 1.5em;
    line-height: 1.43;
}
h4 {
    font-size: 1.25em;
}
h5 {
    font-size: 1em;
}
h6 {
   font-size: 1em;
    color: #777;
}
p,
blockquote,
ul,
ol,
dl,
table{
    margin: 0.8em 0;
}
li>ol,
li>ul {
    margin: 0 0;
}
hr {
    height: 2px;
    padding: 0;
    margin: 16px 0;
    background-color: #e7e7e7;
    border: 0 none;
    overflow: hidden;
    box-sizing: content-box;
}

li p.first {
    display: inline-block;
}
ul,
ol {
    padding-left: 30px;
}
ul:first-child,
ol:first-child {
    margin-top: 0;
}
ul:last-child,
ol:last-child {
    margin-bottom: 0;
}
blockquote {
    border-left: 4px solid #dfe2e5;
    padding: 0 15px;
    color: #777777;
}
blockquote blockquote {
    padding-right: 0;
}
table {
    padding: 0;
    word-break: initial;
}
table tr {
    border: 1px solid #dfe2e5;
    margin: 0;
    padding: 0;
}
table tr:nth-child(2n),
thead {
    background-color: #f8f8f8;
}
table th {
    font-weight: bold;
    border: 1px solid #dfe2e5;
    border-bottom: 0;
    margin: 0;
    padding: 6px 13px;
}
table td {
    border: 1px solid #dfe2e5;
    margin: 0;
    padding: 6px 13px;
}
table th:first-child,
table td:first-child {
    margin-top: 0;
}
table th:last-child,
table td:last-child {
    margin-bottom: 0;
}

.CodeMirror-lines {
    padding-left: 4px;
}

.code-tooltip {
    box-shadow: 0 1px 1px 0 rgba(0,28,36,.3);
    border-top: 1px solid #eef2f2;
}

.md-fences,
code,
tt {
    border: 1px solid #e7eaed;
    background-color: #f8f8f8;
    border-radius: 3px;
    padding: 0;
    padding: 2px 4px 0px 4px;
    font-size: 0.9em;
}

code {
    background-color: #f3f4f4;
    padding: 0 2px 0 2px;
}

.md-fences {
    margin-bottom: 15px;
    margin-top: 15px;
    padding-top: 8px;
    padding-bottom: 6px;
}


.md-task-list-item > input {
  margin-left: -1.3em;
}

@media print {
    html {
        font-size: 13px;
    }
    pre {
        page-break-inside: avoid;
        word-wrap: break-word;
    }
}

.md-fences {
	background-color: #f8f8f8;
}
#write pre.md-meta-block {
	padding: 1rem;
    font-size: 85%;
    line-height: 1.45;
    background-color: #f7f7f7;
    border: 0;
    border-radius: 3px;
    color: #777777;
    margin-top: 0 !important;
}

.mathjax-block>.code-tooltip {
	bottom: .375rem;
}

.md-mathjax-midline {
    background: #fafafa;
}

#write>h3.md-focus:before{
	left: -1.5625rem;
	top: .375rem;
}
#write>h4.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h5.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h6.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
.md-image>.md-meta {
    /*border: 1px solid #ddd;*/
    border-radius: 3px;
    padding: 2px 0px 0px 4px;
    font-size: 0.9em;
    color: inherit;
}

.md-tag {
    color: #a7a7a7;
    opacity: 1;
}

.md-toc { 
    margin-top:20px;
    padding-bottom:20px;
}

.sidebar-tabs {
    border-bottom: none;
}

#typora-quick-open {
    border: 1px solid #ddd;
    background-color: #f8f8f8;
}

#typora-quick-open-item {
    background-color: #FAFAFA;
    border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
    border-style: solid;
    border-width: 1px;
}

/** focus mode */
.on-focus-mode blockquote {
    border-left-color: rgba(85, 85, 85, 0.12);
}

header, .context-menu, .megamenu-content, footer{
    font-family: "Segoe UI", "Arial", sans-serif;
}

.file-node-content:hover .file-node-icon,
.file-node-content:hover .file-node-open-state{
    visibility: visible;
}

.mac-seamless-mode #typora-sidebar {
    background-color: #fafafa;
    background-color: var(--side-bar-bg-color);
}

.mac-os #write{
    caret-color: AccentColor;
}

.md-lang {
    color: #b4654d;
}

/*.html-for-mac {
    --item-hover-bg-color: #E6F0FE;
}*/

#md-notification .btn {
    border: 0;
}

.dropdown-menu .divider {
    border-color: #e5e5e5;
    opacity: 0.4;
}

.ty-preferences .window-content {
    background-color: #fafafa;
}

.ty-preferences .nav-group-item.active {
    color: white;
    background: #999;
}

.menu-item-container a.menu-style-btn {
    background-color: #f5f8fa;
    background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); 
}



</style><title>视频监控系统开发及使用手册</title>
</head>
<body class='typora-export os-windows typora-export-show-outline typora-export-collapse-outline'><div class='typora-export-content'>
<div class="typora-export-sidebar"><div class="outline-content"><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0-前言说明">0 前言说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#01-编译说明">0.1 编译说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#011-特别提示">0.1.1 特别提示</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#012-注意事项">0.1.2 注意事项</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#013-离线地图">0.1.3 离线地图</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#02-目录说明">0.2 目录说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#03-系统说明">0.3 系统说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#04-特别说明">0.4 特别说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#05-相关站点">0.5 相关站点</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#06-功能特点">0.6 功能特点</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#061-软件模块">0.6.1 软件模块</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#062-基础功能">0.6.2 基础功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#063-特色功能">0.6.3 特色功能</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#07-地址格式">0.7 地址格式</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#070-特别提示">0.7.0 特别提示</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#071-通用格式">0.7.1 通用格式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#072-本地设备">0.7.2 本地设备</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#073-本地桌面">0.7.3 本地桌面</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#074-电视频道">0.7.4 电视频道</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#075-视频文件">0.7.5 视频文件</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#076-网友提供">0.7.6 网友提供</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#077-监控设备">0.7.7 监控设备</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0771-海康">0.7.7.1 海康</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0772-大华">0.7.7.2 大华</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0773-常规">0.7.7.3 常规</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#078-指定协议">0.7.8 指定协议</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#08-版本说明">0.8 版本说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#081-精益求精">0.8.1 精益求精</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#082-破茧成蝶">0.8.2 破茧成蝶</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#083-快速迭代">0.8.3 快速迭代</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1-用户登录退出">1 用户登录退出</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11-用户登录">1.1 用户登录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12-用户退出">1.2 用户退出</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#2-主界面操作">2 主界面操作</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#21-模块显示">2.1 模块显示</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#22-模块拖动">2.2 模块拖动</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#23-视频播放">2.3 视频播放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#24-视频截图">2.4 视频截图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#25-删除视频">2.5 删除视频</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#26-画面切换">2.6 画面切换</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#27-声音调节">2.7 声音调节</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#28-视频轮询">2.8 视频轮询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#29-通道交换">2.9 通道交换</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#210-云台控制">2.10 云台控制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#211-设备控制">2.11 设备控制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#212-报警订阅">2.12 报警订阅</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#213-悬浮工具">2.13 悬浮工具</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#214-标签叠加">2.14 标签叠加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#215-图形绘制">2.15 图形绘制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#216-预置巡航">2.16 预置巡航</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#217-标签信息">2.17 标签信息</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#3-视频回放">3 视频回放</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#31-本地回放">3.1 本地回放</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#311-视频查询">3.1.1 视频查询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#312-存储规则">3.1.2 存储规则</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#32-远程回放">3.2 远程回放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#33-设备播放">3.3 设备播放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#34-图片回放">3.4 图片回放</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#341-图片查询">3.4.1 图片查询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#342-存储规则">3.4.2 存储规则</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#343-导出报告">3.4.3 导出报告</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#35-视频上传">3.5 视频上传</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#351-本地设置">3.5.1 本地设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#352-远程设置">3.5.2 远程设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#353-文件加密">3.5.3 文件加密</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#354-功能特点">3.5.4 功能特点</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#4-电子地图">4 电子地图</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#41-双击预览">4.1 双击预览</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#42-图片地图">4.2 图片地图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#43-离线地图">4.3 离线地图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#44-在线地图">4.4 在线地图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#45-路径规划">4.5 路径规划</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#5-日志查询">5 日志查询</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#51-本地日志">5.1 本地日志</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#511-查询记录">5.1.1 查询记录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#512-打印记录">5.1.2 打印记录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#513-导出记录到xls">5.1.3 导出记录到xls</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#514-导出记录到pdf">5.1.4 导出记录到pdf</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#515-删除记录">5.1.5 删除记录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#516-清空记录">5.1.6 清空记录</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#52-设备日志">5.2 设备日志</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#6-系统设置">6 系统设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#61-基本设置">6.1 基本设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#611-常规设置">6.1.1 常规设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#612-视频参数">6.1.2 视频参数</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#613-数据库设置">6.1.3 数据库设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#614-地图配置">6.1.4 地图配置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#615-功能激活">6.1.5 功能激活</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#616-颜色配置">6.1.6 颜色配置</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#62-录像机管理">6.2 录像机管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#621-录像机添加">6.2.1 录像机添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#622-录像机删除">6.2.2 录像机删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#623-录像机清空">6.2.3 录像机清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#624-录像机信息导入">6.2.4 录像机信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#625-录像机信息导出">6.2.5 录像机信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#626-录像机信息打印">6.2.6 录像机信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#627-导出到excel">6.2.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#63-摄像机管理">6.3 摄像机管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#631-摄像机添加">6.3.1 摄像机添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#632-摄像机删除">6.3.2 摄像机删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#633-摄像机清空">6.3.3 摄像机清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#634-摄像机信息导入">6.3.4 摄像机信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#635-摄像机信息导出">6.3.5 摄像机信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#636-摄像机信息打印">6.3.6 摄像机信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#637-导出到excel">6.3.7 导出到Excel</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#638-设备搜索">6.3.8 设备搜索</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#64-轮询配置">6.4 轮询配置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#641-轮询点添加">6.4.1 轮询点添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#642-轮询点删除">6.4.2 轮询点删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#643-轮询点清空">6.4.3 轮询点清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#644-轮询点信息导入">6.4.4 轮询点信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#645-轮询点信息导出">6.4.5 轮询点信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#645-轮询点信息打印">6.4.5 轮询点信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#647-导出到excel">6.4.7 导出到Excel</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#648-参数设置">6.4.8 参数设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#649-批量生成">6.4.9 批量生成</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#6410-分组设置">6.4.10 分组设置</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#65-用户管理">6.5 用户管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#651-用户添加">6.5.1 用户添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#652-用户删除">6.5.2 用户删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#653-用户清空">6.5.3 用户清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#654-用户信息导入">6.5.4 用户信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#655-用户信息导出">6.5.5 用户信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#656-用户信息打印">6.5.6 用户信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#657-导出到excel">6.5.7 导出到Excel</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#658-权限验证">6.5.8 权限验证</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#66-录像计划">6.6 录像计划</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#67-其他设置">6.7 其他设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#661-串口配置">6.6.1 串口配置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#662-网络配置">6.6.2 网络配置</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#7-简易使用步骤">7 简易使用步骤</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#71-添加摄像机">7.1 添加摄像机</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#72-视频播放">7.2 视频播放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#73-云台控制">7.3 云台控制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#74-自动校时">7.4 自动校时</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#75-事件订阅">7.5 事件订阅</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#76-图片参数">7.6 图片参数</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8-内核模块说明">8 内核模块说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#81-视频监控内核">8.1 视频监控内核</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#811-效果图">8.1.1 效果图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#812-基础功能">8.1.2 基础功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#813-特色功能">8.1.3 特色功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#814-视频控件">8.1.4 视频控件</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#82-onvif搜索模块">8.2 onvif搜索模块</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#821-效果图">8.2.1 效果图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#822-功能介绍">8.2.2 功能介绍</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#823-云台说明">8.2.3 云台说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#824-主要功能">8.2.4 主要功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#825-处理流程">8.2.5 处理流程</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#83-gb28181处理模块">8.3 gb28181处理模块</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#9-主界面模块说明">9 主界面模块说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#90-主界面">9.0 主界面</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#901-视频监控-普通模式">9.0.1 视频监控-普通模式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#902-视频监控-全屏模式">9.0.2 视频监控-全屏模式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#903-机器人监控-普通模式">9.0.3 机器人监控-普通模式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#904-机器人监控-全屏模式">9.0.4 机器人监控-全屏模式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#905-无人机监控-普通模式">9.0.5 无人机监控-普通模式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#906-无人机监控-全屏模式">9.0.6 无人机监控-全屏模式</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#91-设备列表">9.1 设备列表</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#92-窗口信息">9.2 窗口信息</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#93-图文警情">9.3 图文警情</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#94-云台控制">9.4 云台控制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#95-设备控制">9.5 设备控制</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#96-预置位置">9.6 预置位置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#97-巡航设置">9.7 巡航设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#98-悬浮地图">9.8 悬浮地图</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#99-飞行轨迹">9.9 飞行轨迹</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#910-备用模块">9.10 备用模块</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#911-数据调试">9.11 数据调试</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#912-运动仿真">9.12 运动仿真</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#913-图像增强">9.13 图像增强</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#914-网页浏览">9.14 网页浏览</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#10-各系统运行图">10 各系统运行图</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#100-样式风格">10.0 样式风格</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#101-windows-7">10.1 windows-7</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#102-windows-11">10.2 windows-11</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#103-linux-ubuntu">10.3 linux-ubuntu</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#104-linux-fedora">10.4 linux-fedora</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#105-linux-centos">10.5 linux-centos</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#106-linux-uos">10.6 linux-uos</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#107-linux-kylin">10.7 linux-kylin</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#108-linux-neokylin">10.8 linux-neokylin</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#109-linux-newstart">10.9 linux-newstart</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1010-linux-debian">10.10 linux-debian</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1011-unix-mac">10.11 unix-mac</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11-程序框架说明">11 程序框架说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#111-整体代码结构">11.1 整体代码结构</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#112-主模块说明">11.2 主模块说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113-子模块说明">11.3 子模块说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1131-第三方类库">11.3.1 第三方类库</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1132-通信及辅助类">11.3.2 通信及辅助类</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11321-模块-api">11.3.2.1 模块-api</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11322-模块-app">11.3.2.2 模块-app</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11323-模块-devicecustom">11.3.2.3 模块-devicecustom</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11324-模块-devicevideo">11.3.2.4 模块-devicevideo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11325-模块-usercontrol">11.3.2.5 模块-usercontrol</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1133-核心通用类库">11.3.3 核心通用类库</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11331-模块-coreaudio">11.3.3.1 模块-core_audio</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11332-模块-corecommon">11.3.3.2 模块-core_common</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11333-模块-corecontrol">11.3.3.3 模块-core_control</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11334-模块-coredataout">11.3.3.4 模块-core_dataout</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11335-模块-coredb">11.3.3.5 模块-core_db</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11336-模块-coreform">11.3.3.6 模块-core_form</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11337-模块-coremap">11.3.3.7 模块-core_map</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11338-模块-coreonvif">11.3.3.8 模块-core_onvif</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11339-模块-coreqthelper">11.3.3.9 模块-core_qthelper</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113310-模块-coretcpfile">11.3.3.10 模块-core_tcpfile</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113311-模块-corevideo">11.3.3.11 模块-core_video</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113312-模块-corevideobase">11.3.3.12 模块-core_videobase</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113313-模块-corevideoffmpeg">11.3.3.13 模块-core_videoffmpeg</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113314-模块-corevideohelper">11.3.3.14 模块-core_videohelper</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113315-模块-corevideoopengl">11.3.3.15 模块-core_videoopengl</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#113316-模块-corewebview">11.3.3.16 模块-core_webview</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1134-界面ui">11.3.4 界面UI</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11341-模块-frmconfig">11.3.4.1 模块-frmconfig</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11342-模块-frmdata">11.3.4.2 模块-frmdata</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11343-模块-frmdemo">11.3.4.3 模块-frmdemo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11344-模块-frmipc">11.3.4.4 模块-frmipc</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11345-模块-frmmain">11.3.4.5 模块-frmmain</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11346-模块-frmmap">11.3.4.6 模块-frmmap</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11347-模块-frmmodule">11.3.4.7 模块-frmmodule</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11348-模块-frmrobot">11.3.4.8 模块-frmrobot</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11349-模块-frmvideo">11.3.4.9 模块-frmvideo</a></div><ul class="outline-children"></ul></li></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12-二次开发说明">12 二次开发说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#121-通用开发环境搭建">12.1 通用开发环境搭建</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#122-不同系统注意事项">12.2 不同系统注意事项</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#123-监控系统组件示例">12.3 监控系统组件示例</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1231-通用辅助">12.3.1 通用辅助</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1232-视频图片">12.3.2 视频图片</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1233-视频控件">12.3.3 视频控件</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1234-视频存储">12.3.4 视频存储</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1235-视频叠加">12.3.5 视频叠加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1236-同步播放">12.3.6 同步播放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1237-音频频谱">12.3.7 音频频谱</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1238-拖曳播放">12.3.8 拖曳播放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1239-视频切换">12.3.9 视频切换</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12310-标签图形">12.3.10 标签图形</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12311-文字水印">12.3.11 文字水印</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#124-人工智能集成">12.4 人工智能集成</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#13-其他说明">13 其他说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#131-海康onvif设置">13.1 海康onvif设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#132-大华onvif设置">13.2 大华onvif设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#133-国际onvif工具">13.3 国际onvif工具</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#134-报警输入设置">13.4 报警输入设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#135-环境使用qtvs">13.5 环境使用qt+vs</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#136-数据库设置mysql">13.6 数据库设置mysql</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#137-打开本地摄像头">13.7 打开本地摄像头</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#138-项目代码行数">13.8 项目代码行数</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#139-编译ffmpeg">13.9 编译ffmpeg</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1391-本地编译">13.9.1 本地编译</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1392-交叉编译">13.9.2 交叉编译</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1393-编译x264x265">13.9.3 编译x264/x265</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1394-硬件解码">13.9.4 硬件解码</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1310-高分屏缩放">13.10 高分屏缩放</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1311-浏览器内核">13.11 浏览器内核</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1312-odbc数据源">13.12 ODBC数据源</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1313-摄像机音频设置">13.13 摄像机音频设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1314-数据库插件">13.14 数据库插件</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1315-端口映射">13.15 端口映射</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1316-linux-wayland">13.16 linux-wayland</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1317---no-sandbox">13.17 --no-sandbox</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1318-秘钥控制">13.18 秘钥控制</a></div><ul class="outline-children"></ul></li></ul></li></div></div><div id='write'  class=''><h2 id='0-前言说明'><span>0 前言说明</span></h2><h3 id='01-编译说明'><span>0.1 编译说明</span></h3><h4 id='011-特别提示'><span>0.1.1 特别提示</span></h4><ol start='' ><li><p><span>本系统没有说基于哪个Qt版本，由于系统中电子地图模块用到了浏览器模块，所以理论上要求你电脑的Qt版本也有浏览器模块才行</span></p></li><li><p><span>如果没有浏览器模块则电子地图模块不可用，但是其余功能全部可用，没有任何影响。</span></p></li><li><p><span>本人亲测Qt4.7到Qt6.7之间的所有版本（理论上支持后续所有版本），亲测msvc、mingw、gcc、clang、armgcc各种编译器，亲测xp、win7、win10、linux、mac、树莓派、香橙派、全志H3、cotex-A9、imx6等。</span></p></li><li><p><span>2021-1-6开始集成了miniblink浏览器内核，意味着mingw版本的qt5.6以上版本也全部支持，这样就所有系统都有浏览器模块不需要担心没有电子地图的问题。Qt6.4.1到Qt6.5.1之间的版本，miniblink浏览器控件会和openglwidget冲突导致白屏，建议避开这几个版本。</span></p></li><li><p><span>部分构建套件可能不支持预编译头，预编译头仅仅是为了加快编译速度，和程序本身无关。比如在win+Qt5.5 5.6就发现不支持，也可能是支持的不够全面，如果编译发生错误可以试着打开pro文件注释掉PRECOMPILED_HEADER = head.h  这行。</span></p></li><li><p><span>Qt6.2的mingw版本的multimedia模块不可用，msvc版本的正常。</span></p></li><li><p><span>开启视频存储后默认存储的MP4格式的文件，如果想要调整体积大小，可以找到core/core_videoffmpeg/ffmpegsave.cpp videoCodecCtx-&gt;bit_rate = FFmpegHelper::getBitRate(videoWidth, videoHeight); 将这个码率调小即可，比如 videoCodecCtx-&gt;bit_rate = FFmpegHelper::getBitRate(videoWidth, videoHeight)/2; 可以将体积减少一半，相应的画质也会差一些。</span></p></li><li><p><strong><span>推荐用64位的Qt搭配64位的ffmpeg，目前绝大部分系统都是64位的，能获得最大性能提升，本人亲自对比测试32位和64位，64位无论资源占用和操作响应等体验都更优。尤其是开启硬解码后，如果64个通道都需要硬解码，32位的测试下来貌似资源不够用。</span></strong></p></li><li><p><span>如果更改appconfig.cpp中的值发现没有变化，那是因为里面的值是用来默认生成配置文件的值，如果配置文件已经存在，则对应变量是从配置文件读取的值，如果想要更改后的默认值生效，需要删除配置文件(config/video_system.ini)重新打开程序即可。</span></p></li><li><p><span>内核ffmpeg画框画文字水印等采用的滤镜实现，默认硬解码的数据是NV12不支持滤镜，意味着画框等无效，绘制文字有效，如果一定要在硬解码的帧数据画框，可以使用包含各种形状比如正方形/三角形/矩形的图形字体，指定图形字体的值来绘制。</span></p></li><li><p><span>如果在linux系统编译提示 -disable-new-dtags: unknown option ，打开core_videobase/core_videobase_include.pri ，把底部 DTAGS = ,-disable-new-dtags 整行注释就行。</span></p></li><li><p><span>关于声音的几点说明：系统中有多个声音相关的控制参数，一个是decodeAudio，用于控制是否解码音频数据；一个是playAudio，用于控制是否将解码后的音频数据发到声卡进行播放；一个是soundMute，用于控制声音大小为静音；在视频控件上的音量图标切换是用于切换静音。音频振幅也就是音柱的变化，只要声卡那边有数据播放，无论静音与否，都会有音频振幅效果。</span></p></li></ol><h4 id='012-注意事项'><span>0.1.2 注意事项</span></h4><ol start='' ><li><p><span>可执行文件在源码同级目录的bin目录下。</span></p></li><li><p><span>编译完成后记得将源码下的file目录下（切记是file目录下而不是file目录）的所有文件复制到可执行文件同一目录。</span></p></li><li><p><span>如果开启了视频监控（默认开启），则记得将对应的动态库文件复制到可执行文件同一目录。比如采用ffmpeg内核（默认就是ffmpeg）的话，则将下载到的dll_ffmpeg4下的所有文件复制到可执行文件同一目录。</span></p></li><li><p><span>各个操作系统对应的ffmpeg编译好的动态库以及miniblink的动态库下载地址。</span>
<a href='https://pan.baidu.com/s/13LDRu6mXC6gaADtrGprNVA' target='_blank' class='url'>https://pan.baidu.com/s/13LDRu6mXC6gaADtrGprNVA</a><span>  提取码: ujm7。</span></p></li><li><p><span>如果是64位的qt则对应的dll是拷贝dll_ffmpeg4_64目录下的，64位的linux对应的是liblinux64.tar.gz。</span></p></li><li><p><span>本系统支持ffmpeg2/3/4/5/6所有版本，默认是ffmpeg4，如果要支持XP需要用ffmpeg2/3。如果是在linux/mac系统上编译记得查看core_videoffmpeg/下面的 linux系统和mac系统上库的用法.txt/编译阶段linux系统ffmpeg库放置位置.jpg/运行阶段linux系统ffmpeg库放置位置.jpg。</span></p></li><li><p><span>如果编译运行提示miniblink文件不存在请先拷贝，则说明你当前用的Qt版本没有浏览器模块，要么没安装，要么不支持，你也不用担心啥，此时自动切换用的miniblink浏览器内核，你还需要将ffmpeg库下载的网盘的地方找到dll_miniblink.zip下载解压到可执行文件同一目录即可。</span></p></li><li><p><span>系统中所有的图标，都采用的图形字体，对照表在doc目录下的FontAwesome.png、FontAliBaBa.png，对应图形字体类IconHelper中加载的图形字体，后期如果还有增加的其他图形字体也是放在这里，一个类支持多种图形字体，通过不同的值范围自动设置。</span></p></li><li><p><span>如果发现地图打不开或者提示秘钥文件丢失，请先确认file目录下的所有文件有没有拷贝过去。</span></p></li><li><p><span>如果是用vs+qt可能报错 error LNK2026，解决办法详细见本文档中13其他说明/13.5环境使用qt+vs。</span></p></li><li><p><span>默认用户名admin  密码admin。</span></p></li><li><p><span>系统配置参数在加载的时候会对节点值进行过滤判断，如果为空会自动用初始值生成新的配置文件，如果不想要显示版权所有公司，可以填xxx而不是删掉整个值。</span></p></li><li><p><span>如果是用vlc推流的rtsp地址，比如 rtsp://:8554/aabb，由于vlc推流默认写死的采用的udp协议，所以监控系统也必须在系统设置中通信方式选择udp才行（默认tcp）。</span></p></li></ol><h4 id='013-离线地图'><span>0.1.3 离线地图</span></h4><ol start='' ><li><p><span>离线地图可以用网上的瓦片地图下载器下载百度的离线地图放到对应目录即可。</span></p></li><li><p><span>也可以直接下载网盘中已经下载好的上海市的离线地图。</span></p></li><li><p><span>下载地址：</span><a href='https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A' target='_blank' class='url'>https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A</a><span>  提取码：o05q  文件名称：bin_map_tiles.tar.xz</span></p></li></ol><p><strong><span>使用说明</span></strong></p><ol start='' ><li><p><span>将压缩包下的两个文件夹复制到对应可执行文件下的config文件夹下，和map.js文件同一级目录。</span></p></li><li><p><span>tiles文件夹是街道图，tiles_hybrid文件夹是卫星图，tiles_self是路网图，路网图和卫星图合并就是混合图。</span></p></li><li><p><span>默认提供的是上海市徐汇区的瓦片地图，如果自己用万能地图下载器下载的百度地图的瓦片文件，也可以对应替换就行。</span></p></li><li><p><span>要注意的是格式，默认是jpg，如果下载的瓦片地图格式是png则需要打开config文件夹下的map_load.js文件，将.jpg改成.png保存即可。</span></p></li></ol><h3 id='02-目录说明'><span>0.2 目录说明</span></h3><ol start='' ><li><p><span>本源码项目文件中对编译生成的临时文件和可执行文件做了重定向，可执行文件并不在build开头的目录下，而是在源码同级目录的bin目录下。</span></p></li><li><p><span>config目录放的是软件的配置文件、地图模块需要的图片资源等。</span></p></li><li><p><span>db目录一般有三个文件，key.db是秘钥文件、video_system.db是对应sqlite的数据库文件、video_system.sql是对应数据库脚本（可以在系统设置中数据库管理部分执行脚本用来切换到mysql等其他数据库）。</span></p></li><li><p><span>logo目录存放的各种左上角软件LOGO图片，可以在系统设置中下拉选择。</span></p></li><li><p><span>map目录存放的图片地图模块所用的地图图片文件，可以手动拷贝到此。</span></p></li><li><p><span>sound目录存放的本系统所用的声音文件。</span></p></li><li><p><span>layout目录存放的不同工作模式不同界面对应的布局方案配置文件。</span></p></li></ol><h3 id='03-系统说明'><span>0.3 系统说明</span></h3><ol start='' ><li><p><span>本视频监控系统做的是通用的系统，主要偏重整体框架和UI交互等。</span></p></li><li><p><span>主要功能包括摄像机管理，实时视频显示，视频轮询、视频存储、设备地图显示，各种画面切换，各种悬停子模块、onvif搜索设备和云台控制及预置位，通用的NVR视频流播放（比如海康的NVR支持直接取流回放），录像计划、用户管理等功能。</span></p></li><li><p><span>如果是依赖SDK去实现的功能（雨刷、去雾等）都没有做，那个破坏了兼容性，无法通用其他摄像机设备以及其他操作系统。</span></p></li><li><p><span>每个厂家SDK和定制的功能都不一样，如果有这方面的需要都是买过去自己加上SDK的功能和自己定制需要的功能。</span></p></li><li><p><span>整个项目源代码行数大概30W行（项目代码本身除去第三方库以后约7W行，就是自己写的部分），其中代码13.5W行（占比45%），注释12.7W行（占比42%），空行3.5W行。分层设计注释详细。</span></p></li><li><p><span>本程序会一直持续迭代更新，包括项目源码、整体框架、使用说明等，一次购买终生售后。</span></p></li></ol><h3 id='04-特别说明'><span>0.4 特别说明</span></h3><ol start='' ><li><p><span>程序本身是个客户端（直接从摄像机或者NVR等设备取rtsp视频流）并不是服务器程序。</span></p></li><li><p><span>摄像机管理没有限制摄像机的数量，理论上10000路肯定没有问题，就是个数据库记录。</span></p></li><li><p><span>实时显示具体能支持多少路，和具体的电脑配置有关（亲测1.8G主频8G内存I5子码流64路，总之比海康大华客户端要更优秀）。</span></p></li><li><p><span>程序实时显示界面最大可以到64路，每个通道都是打开的时候才会去建立连接取视频流，而不是一开始就建立了连接。</span></p></li><li><p><span>系统采用onvif协议+rtsp视频流机制，并不限定支持哪家的摄像机，只要符合这两种协议的都支持，市面上99%的网络摄像机都支持这两种基础协议，包括但不限于海康、大华、宇视、天地伟业、华为等各种安防厂家的摄像机。</span></p></li><li><p><span>本系统没有内置人脸识别等任何相关算法，提供的是相关的接口，比如自己的算法识别到人脸区域后，将区域坐标传入视频控件自动绘制。</span></p></li><li><p><span>系统采用纯QtWidget（非qml）编写，解码采用ffmpeg，搜索采用onvif协议，视频播放采用rtsp协议，所有源码开放，没有封装的库。</span></p></li><li><p><span>同时集成了数据库、多线程、串口通信、网络通信、音视频解码/同步/存储、网页地图、界面美化、UI布局等众多知识点。</span></p></li><li><p><span>未经本人许可不可将本项目源码扩散，如有发现本人将追究法律责任，谢谢配合。</span></p></li></ol><h3 id='05-相关站点'><span>0.5 相关站点</span></h3><ol start='' ><li><p><span>国内站点：</span><a href='https://gitee.com/feiyangqingyun'><span>https://gitee.com/feiyangqingyun</span></a></p></li><li><p><span>国际站点：</span><a href='https://github.com/feiyangqingyun'><span>https://github.com/feiyangqingyun</span></a></p></li><li><p><span>个人主页：</span><a href='https://blog.csdn.net/feiyangqingyun'><span>https://blog.csdn.net/feiyangqingyun</span></a></p></li><li><p><span>知乎主页：</span><a href='https://www.zhihu.com/people/feiyangqingyun'><span>https://www.zhihu.com/people/feiyangqingyun</span></a></p></li><li><p><span>产品主页：</span><a href='https://blog.csdn.net/feiyangqingyun/article/details/97565652'><span>https://blog.csdn.net/feiyangqingyun/article/details/97565652</span></a></p></li><li><p><span>在线文档：</span><a href='https://feiyangqingyun.gitee.io/qwidgetdemo/video_system/'><span>https://feiyangqingyun.gitee.io/qwidgetdemo/video_system/</span></a></p></li><li><p><span>体验地址：</span><a href='https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g'><span>https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g</span></a><span>  提取码：01jf 文件名：bin_video_system.zip。</span></p></li><li><p><span>文章导航：</span><a href='https://qtchina.blog.csdn.net/article/details/121327495'><span>https://qtchina.blog.csdn.net/article/details/121327495</span></a></p></li></ol><h3 id='06-功能特点'><span>0.6 功能特点</span></h3><h4 id='061-软件模块'><span>0.6.1 软件模块</span></h4><ol start='' ><li><p><span>视频监控模块，各种停靠小窗体子模块，包括设备列表、图文警情、窗口信息、云台控制、预置位、巡航设置、设备控制、悬浮地图、网页浏览等。</span></p></li><li><p><span>视频回放模块，包括本地回放、远程回放、设备播放、图片回放、视频上传等。</span></p></li><li><p><span>电子地图模块，包括图片地图、在线地图、离线地图、路径规划等。</span></p></li><li><p><span>日志查询模块，包括本地日志、设备日志等。</span></p></li><li><p><span>系统设置模块，包括系统设置（基本设置、视频参数、数据库设置、地图配置、串口配置等）、录像机管理、摄像机管理、轮询配置、录像计划、用户管理等。</span></p></li></ol><h4 id='062-基础功能'><span>0.6.2 基础功能</span></h4><ol start='' ><li><p><span>支持各种视频流（rtsp、rtmp、http等）、视频文件（mp4、rmvb、avi等）、本地USB摄像机播放。</span></p></li><li><p><span>支持多画面切换，包括1、4、6、8、9、13、16、25、36、64画面切换。</span></p></li><li><p><span>支持全屏切换，多种切换方式包括鼠标右键菜单、工具栏按钮、快捷键（alt+enter全屏，esc退出全屏）。</span></p></li><li><p><span>支持视频轮询，包括1、4、9、16画面轮询，可设置轮询分组（轮询预案）、轮询间隔、码流类型等。</span></p></li><li><p><span>支持onvif协议，包括设备搜索、云台控制、预置位、设备控制（图片参数、校对时间、系统重启，抓拍图片等）。</span></p></li><li><p><span>支持权限管理，不同的用户可以对应不同的模块权限，比如删除日志、关闭系统等。</span></p></li><li><p><span>数据库支持多种，包括sqlite、mysql、sqlserver、postgresql、oracle、人大金仓等。</span></p></li><li><p><span>本地USB摄像机支持设置分辨率、帧率等参数。</span></p></li><li><p><span>所有停靠模块都自动生成对应的菜单用来控制显示和隐藏，在标题栏右键可以弹出。</span></p></li><li><p><span>支持显示所有模块、隐藏所有模块、复位普通布局、复位全屏布局。</span></p></li><li><p><span>双击设备弹出实时预览视频，支持图片地图、在线地图、离线地图等。</span></p></li><li><p><span>摄像机节点拖曳到对应窗体播放视频，同时支持拖曳本地文件直接播放。</span></p></li><li><p><span>删除视频支持鼠标右键删除、悬浮条关闭删除、拖曳到视频监控面板外删除等多种方式。</span></p></li><li><p><span>图片地图上设备按钮可自由拖动，自动保存位置信息。百度地图上可以鼠标单击获取经纬度信息，用来更新设备位置。</span></p></li><li><p><span>视频监控面板窗体中任意通道支持拖曳交换，瞬间响应。</span></p></li><li><p><span>封装了百度地图，视图切换，运动轨迹，设备点位，鼠标按下获取经纬度等。</span></p></li><li><p><span>双击节点、拖曳节点、拖曳窗体交换位置等操作，均自动更新保存最后的播放地址，下次软件打开自动应用。</span></p></li><li><p><span>右下角音量条控件，失去焦点自动隐藏，音量条带静音图标，自动记忆最后的音量及静音状态。</span></p></li><li><p><span>支持视频截图，可指定单个或者对所有通道截图，底部小工具栏也有截图按钮，每个视频控件悬浮条也有抓拍按钮。</span></p></li><li><p><span>支持超时自动隐藏鼠标指针、自动全屏机制。</span></p></li><li><p><span>支持onvif云台控制，可上下左右移动云台摄像机，包括复位和焦距调整等。</span></p></li><li><p><span>支持onvif预置位，可以添加、删除、修改预置位，可以调用起始位。</span></p></li><li><p><span>支持OSD增删改查，可以通过onvif协议添加及修改OSD信息。</span></p></li><li><p><span>支持onvif图像参数设置，包括明亮度、对比度、饱和度、尖锐度等。</span></p></li><li><p><span>支持onvif其他操作，包括抓图、网络设置、校时、重启、事件订阅等。</span></p></li><li><p><span>支持任意onvif摄像机，包括但不限于海康、大华、宇视、天地伟业、华为等。</span></p></li><li><p><span>可保存视频，可通过录像计划存储，也可在悬浮条手动切换开始录像和停止录像。</span></p></li><li><p><span>可设置视频流通信方式tcp或udp，可设置视频解码是速度优先、质量优先、均衡处理、最快速度等。</span></p></li><li><p><span>可设置软件中文名称、英文名称、LOGO图标等。</span></p></li><li><p><span>存储的视频文件支持导出到指定目录，支持批量上传到服务器。</span></p></li><li><p><span>完善的录像计划设置，支持每个通道7 * 24小时每半小时设置是否存储录像。</span></p></li><li><p><span>音视频同步显示以及音视频同步存储到MP4文件。</span></p></li></ol><h4 id='063-特色功能'><span>0.6.3 特色功能</span></h4><ol start='' ><li><p><span>主界面采用停靠窗体模式，各种组件以小模块的形式加入，可自定义任意模块加入。</span></p></li><li><p><span>停靠模块可拖动任意位置嵌入和悬浮，支持最大化全屏，支持多屏幕。</span></p></li><li><p><span>双重布局文件存储机制，正常模式、全屏模式都对应不同的布局方案，自动切换和保存，比如全屏模式可以突出几个模块透明显示在指定位置，更具科幻感现代化。</span></p></li><li><p><span>原创onvif协议机制，采用底层协议解析（udp广播搜索+http请求执行命令）更轻量易懂易学习拓展，不依赖任何第三方组件比如gsoap。</span></p></li><li><p><span>原创数据导入、导出、打印机制，跨平台不依赖任何组件，瞬间导出数据。</span></p></li><li><p><span>内置多个原创组件，宇宙超值超级牛逼，包括数据导入导出组件（导出到xls、pdf、打印）、数据库组件（数据库管理线程、自动清理数据线程、万能分页、数据请求等）、地图组件、视频监控组件、文件多线程收发组件、onvif通信组件、通用浏览器内核组件等。</span></p></li><li><p><span>自定义信息框+错误框+询问框+右下角提示框（包含多种格式）等。</span></p></li><li><p><span>精美换肤，高达20套皮肤样式随意更换，所有样式全部统一，包括菜单等。</span></p></li><li><p><span>选中通道对应设备树节点高亮，选中通道节点对应视频控件高亮，方便查看当前通道信息。</span></p></li><li><p><span>视频控件悬浮条可以自行增加多个按钮，监控界面底部小工具栏也可自行增加按钮。</span></p></li><li><p><span>双击摄像机节点自动播放视频，双击节点自动依次添加视频，会自动跳到下一个，双击父节点自动添加该节点下的所有视频。可选主码流、子码流。</span></p></li><li><p><span>录像机管理、摄像机管理，可添加删除修改导入导出打印信息，立即应用新的设备信息生成树状列表，不需重启。</span></p></li><li><p><span>可选多种内核自由切换，ffmpeg、vlc、mpv等，均可在pro中设置。推荐用ffmpeg，跨平台最多，默认提供好了linux和mac平台上编译好的库。</span></p></li><li><p><span>支持硬解码，可设置硬解码类型（qsv、dxva2、d3d11va等）。</span></p></li><li><p><span>默认采用opengl绘制视频，超低的CPU资源占用，支持yuyv和nv12两种格式绘制，性能爆表。</span></p></li><li><p><span>标签和图形信息支持三种绘制方式，绘制到遮罩层、绘制到图片、源头绘制（对应信息可以存储到文件）。</span></p></li><li><p><span>包括但不限于视频监控内核组件的所有功能，可参阅说明书中功能介绍 </span><a href='#81-视频监控内核'><span>视频监控内核</span></a><span>。</span></p></li><li><p><span>高度可定制化，用户可以很方便的在此基础上衍生自己的功能，比如增加自定义模块，增加运行模式、机器人监控、无人机监控、挖掘机监控等。</span></p></li><li><p><span>支持xp、win7、win10、win11、linux、mac、各种国产系统（UOS、中标麒麟、银河麒麟等）、嵌入式linux等系统。</span></p></li><li><p><span>注释完整，项目结构清晰，超级详细完整的使用开发手册，精确到每个代码文件的功能说明，不断持续迭代版本。</span></p></li></ol><h3 id='07-地址格式'><span>0.7 地址格式</span></h3><h4 id='070-特别提示'><span>0.7.0 特别提示</span></h4><ol start='' ><li><p><span>由于编解码涉及到很多参数，一般都按照默认参数进行处理。</span></p></li><li><p><span>部分用户有时候希望通过填入的播放地址就带上这些信息，比如通信协议、桌面采集的分辨率、编码保存是否转码、转码是否缩放原图等。</span></p></li><li><p><span>各种参数设置有个优先级，优先取地址中带的，没有带则取结构体中的，还没有则取默认值。</span></p></li><li><p><span>有些值会根据具体情况自动调整，比如本地设备采集没有硬解码，udp开头的视频流强制用udp协议，有些不支持硬解的格式自动将硬解码=none。</span></p></li><li><p><span>对于需要在地址中指定参数，对应占位符不填的需要占位符留空，不可以跳过。</span></p></li><li><p><span>占位符中填了对应参数的必须严格按照指定的格式要求，不按照则很可能导致解析失败。</span></p></li><li><p><span>参数用英文竖杠 | 隔开。</span></p></li></ol><h4 id='071-通用格式'><span>0.7.1 通用格式</span></h4><ol start='' ><li><p><strong><span>格式要求: url|transport|decodeType|encodeVideo|encodeVideoFps|encodeVideoRatio|encodeVideoScale。</span></strong></p></li><li><p><span>url表示媒体地址，比如 f:/1.mp3 d:/1.mp4 rtsp://192.168.0.100 等。</span></p></li><li><p><span>transport表示通信协议，可选 tcp/udp，一般用于rtsp视频流，很多时候在linux系统中必须指定tcp，rtsp摄像头才能正常采集。</span></p></li><li><p><span>decodeType表示解码策略，0-速度优先，1-质量优先，2-均衡处理，3-最快速度（不做音视频同步，收到就立马解码和显示）。</span></p></li><li><p><span>encodeVideo表示视频编码格式，0-不做处理，1-自动转码(源头是264就264/265就265)，2-强制用264编码，3-强制用265编码。</span></p></li><li><p><span>encodeVideoFps表示编码帧率，默认取源头流的帧率，如果指定了则取指定的。</span></p></li><li><p><span>encodeVideoRatio表示视频压缩比率，对应bit_rate的值，在不改变分辨率的情况下，通过调整这个参数来控制保存文件体积的大小。范围值0-1。</span></p></li><li><p><span>encodeVideoScale表示视频缩放值，字符串类型，如果值float值，则相当于在原有分辨率按照这个值等比例缩放，比如encodeVideoScale=0.5，视频源分辨率是1920x720，则编码保存按照960x360这个分辨率保存。如果是640x480，则按照指定的这个分辨率强制缩放，可能会变形。</span></p></li></ol><h4 id='072-本地设备'><span>0.7.2 本地设备</span></h4><ol start='' ><li><p><strong><span>格式要求：url|bufferSize|frameRate|codecName。</span></strong></p></li><li><p><span>url表示媒体地址，采集摄像头统一约定 video=或者audio=开头。</span></p></li><li><p><span>bufferSize表示分辨率，可填1280x720这种，不填默认640x480。</span></p></li><li><p><span>frameRate表示帧率，不填默认25。</span></p></li><li><p><span>codecName表示解码器名称，有些本地摄像头可以指定解码器名称比如mjpeg/h264，前提是要该设备支持该解码器。默认为空则不指定会自动处理。</span></p></li><li><p><span>win系统如何查看设备名见本文档中 </span><a href='#137-打开本地摄像头'><span>打开本地摄像头</span></a><span>。</span></p></li><li><p><span>linux系统查看设备名直接执行命令 ls /dev/video *  即可，一般对应的设备名是 /dev/video0。</span></p></li><li><p><span>下面假定本地摄像头的设备名为 USB Video Device。</span></p></li><li><p><span>写法1：video=USB Video Device，这种写法默认按照640x480分辨率打开摄像头。</span></p></li><li><p><span>写法2：video=USB Video Device|1280x720|30，这种写法按照指定的分辨率1280x720以及采集帧率30来打开摄像头。</span></p></li><li><p><span>写法3：video=/dev/video0，这种是对应linux系统，程序内部会自动过滤和调整填入的地址。</span></p></li><li><p><span>写法4：audio=麦克风 (USB Audio Device)，只采集本地麦克风。</span></p></li><li><p><span>写法5：video=USB Video Device:audio=麦克风 (USB Audio Device)，同时采集本地摄像头和麦克风。</span></p></li><li><p><span>写法6：video=USB Video Device|1920x1080|30|h264，按照1080P分辨率30帧h264格式解码来打开摄像头。</span></p></li><li><p><span>约定audio=开头是只采集音频，video=开头可以采集视频或者视音频。</span></p></li><li><p><span>如果指定了分辨率和帧率则需要硬件支持才行，比如摄像头的最大分辨率是640x480，而指定了1280x720则会打开失败。</span></p></li></ol><h4 id='073-本地桌面'><span>0.7.3 本地桌面</span></h4><ol start='' ><li><p><strong><span>格式要求：url|bufferSize|frameRate|offsetX|offsetY|screenIndex|encodeVideoScale。</span></strong></p></li><li><p><span>url表示媒体地址，采集桌面统一约定 screen=开头。</span></p></li><li><p><span>bufferSize表示采集分辨率，不填则默认取屏幕分辨率。</span></p></li><li><p><span>frameRate表示采集帧率，基本上在2-30之间，不填的话默认ffmpeg会设定一个值，有时候是30。</span></p></li><li><p><span>offsetX/offsetY表示偏移值XY坐标，从屏幕的左上角（0,0）开始。</span></p></li><li><p><span>screenIndex表示屏幕索引，不填的话则默认取当前鼠标所在屏幕。在多个屏幕的时候可通过此参数指定屏幕索引。</span></p></li><li><p><span>encodeVideoScale表示缩放，1表示原始比例（默认值1），0.2则表示按照原始分辨率等比例0.2倍缩放，也可以填400x300表示强制按照这个分辨率缩放。这个在高分辨率的时候特别有用，比如采集的桌面分辨率很大，但是传输的时候受限于带宽，需要等比例压缩一下再传输，此时可以填0.5/0.2之类的值。</span></p></li><li><p><span>写法1：screen=desktop，当前屏幕全屏采集。</span></p></li><li><p><span>写法2：screen=desktop||15|0|0|1，屏幕2全屏采集，帧率15。</span></p></li><li><p><span>写法3：screen=desktop|800x600|10|50|100，鼠标所在当前屏幕采集，采集区域rect（50,100,800,600），帧率10。</span></p></li><li><p><span>写法4：screen=desktop|10x10，约定10x10分辨率表示所有屏幕合并到一个屏幕采集，比如两个屏幕的时候，当做一个屏幕整体采集。当合并屏幕采集的时候，XY偏移值参数无效。</span></p></li><li><p><span>写法5：screen=desktop|800x600|25|1500|300|255，约定屏幕索引255则取用户自定义的区域，该字符串表示采集区域是(1500, 300, 800, 600)，自由区域，可以任意指定，比如两个屏幕中间区域。前提只要保证该区域在两个屏幕区域中，如果超过了的话可能采集失败，这要求用户需要对采集区域精准定位。</span></p></li><li><p><span>写法6：screen=title=MainWindow，对指定窗口标题是MainWindow的窗体采集。支持中文标题比如screen=title=系统设置。</span></p></li><li><p><strong><span>经过大量测试发现，如果打包发布的Qt程序带了qt.conf文件并且里面指定了 WindowsArguments = dpiawareness=0 ，在电脑分辨率设置了缩放比不为100%的时候，计算出来的桌面区域未必正确，建议如果此种情况下一定要采集正确的桌面，去掉qt.conf文件中的对应内容或者删除qt.conf文件即可。</span></strong></p></li></ol><h4 id='074-电视频道'><span>0.7.4 电视频道</span></h4><ol start='' ><li><p><span>中央综合：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225618/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225618/index.m3u8</a></p></li><li><p><span>中央新闻：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225638/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225638/index.m3u8</a></p></li><li><p><span>中央音乐：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225641/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225641/index.m3u8</a></p></li><li><p><span>中央电视：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225635/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225635/index.m3u8</a></p></li><li><p><span>中央记录：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225646/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225646/index.m3u8</a></p></li><li><p><span>中央少儿：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225639/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225639/index.m3u8</a></p></li><li><p><span>湖南卫视：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225745/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225745/index.m3u8</a></p></li><li><p><span>深圳卫视：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225741/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225741/index.m3u8</a></p></li><li><p><span>上海纪实：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225654/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225654/index.m3u8</a></p></li><li><p><span>天津卫视：</span><a href='http://39.135.138.60:18890/PLTV/88888910/224/3221225739/index.m3u8' target='_blank' class='url'>http://39.135.138.60:18890/PLTV/88888910/224/3221225739/index.m3u8</a></p></li></ol><h4 id='075-视频文件'><span>0.7.5 视频文件</span></h4><p><span> </span><img src="snap/0-7-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>万能办法，用谷歌或者谷歌内核的浏览器，打开时光网 </span><a href='http://www.mtime.com/' target='_blank' class='url'>http://www.mtime.com/</a><span> ，随便打开个视频，这里一般是预告片，按F12切换到审查元素，顶部切换到网络，选中媒体，刷新网页，按照尺寸排列，最大的那个MP4文件就是，鼠标右键复制地址，这个地址就是完整的网络地址。</span></strong></p><ol start='' ><li><p><a href='http://vfx.mtime.cn/Video/2021/11/16/mp4/211116131456748178.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2021/11/16/mp4/211116131456748178.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2023/03/09/mp4/230309152143524121.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2023/03/09/mp4/230309152143524121.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2023/03/07/mp4/230307085324679124.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2023/03/07/mp4/230307085324679124.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2022/07/18/mp4/220718132929585151.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2022/07/18/mp4/220718132929585151.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2022/12/17/mp4/221217153424902164.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2022/12/17/mp4/221217153424902164.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2022/07/04/mp4/220704110656040153.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2022/07/04/mp4/220704110656040153.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2021/02/08/mp4/210208150307073134.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2021/02/08/mp4/210208150307073134.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2021/05/11/mp4/210511114524329144.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2021/05/11/mp4/210511114524329144.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2021/04/20/mp4/210420113022586184.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2021/04/20/mp4/210420113022586184.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2021/03/13/mp4/210313111010421158.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2021/03/13/mp4/210313111010421158.mp4</a></p></li><li><p><a href='http://vfx.mtime.cn/Video/2020/01/15/mp4/200115125943120574.mp4' target='_blank' class='url'>http://vfx.mtime.cn/Video/2020/01/15/mp4/200115125943120574.mp4</a></p></li></ol><p><span>百度视频</span></p><ol start='' ><li><p><a href='https://vd2.bdstatic.com/mda-nhpqy7k8xamgiqw3/720p/h264/1661362621500413748/mda-nhpqy7k8xamgiqw3.mp4' target='_blank' class='url'>https://vd2.bdstatic.com/mda-nhpqy7k8xamgiqw3/720p/h264/1661362621500413748/mda-nhpqy7k8xamgiqw3.mp4</a></p></li><li><p><a href='https://vd2.bdstatic.com/mda-nhp9zvu4tiinsp7z/576p/h264/1661324637707658476/mda-nhp9zvu4tiinsp7z.mp4' target='_blank' class='url'>https://vd2.bdstatic.com/mda-nhp9zvu4tiinsp7z/576p/h264/1661324637707658476/mda-nhp9zvu4tiinsp7z.mp4</a></p></li><li><p><a href='https://vd4.bdstatic.com/mda-nhp77xn7fx3e0jgb/576p/h264/1661317610850513689/mda-nhp77xn7fx3e0jgb.mp4' target='_blank' class='url'>https://vd4.bdstatic.com/mda-nhp77xn7fx3e0jgb/576p/h264/1661317610850513689/mda-nhp77xn7fx3e0jgb.mp4</a></p></li><li><p><a href='https://vd2.bdstatic.com/mda-nhp72n8xvbtdcmcq/576p/h264/1661317214259599500/mda-nhp72n8xvbtdcmcq.mp4' target='_blank' class='url'>https://vd2.bdstatic.com/mda-nhp72n8xvbtdcmcq/576p/h264/1661317214259599500/mda-nhp72n8xvbtdcmcq.mp4</a></p></li><li><p><a href='https://vd2.bdstatic.com/mda-nhp6z0in87tvw77v/576p/h264/1661316943890074768/mda-nhp6z0in87tvw77v.mp4' target='_blank' class='url'>https://vd2.bdstatic.com/mda-nhp6z0in87tvw77v/576p/h264/1661316943890074768/mda-nhp6z0in87tvw77v.mp4</a></p></li><li><p><a href='http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4' target='_blank' class='url'>http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4</a></p></li><li><p><a href='http://vd2.bdstatic.com/mda-mhhf5mr00yyhpfjs/1080p/cae_h264/1629284581057661229/mda-mhhf5mr00yyhpfjs.mp4' target='_blank' class='url'>http://vd2.bdstatic.com/mda-mhhf5mr00yyhpfjs/1080p/cae_h264/1629284581057661229/mda-mhhf5mr00yyhpfjs.mp4</a></p></li><li><p><a href='http://vd2.bdstatic.com/mda-mhig1c3sw223mx8p/1080p/cae_h264/1629380139191731149/mda-mhig1c3sw223mx8p.mp4' target='_blank' class='url'>http://vd2.bdstatic.com/mda-mhig1c3sw223mx8p/1080p/cae_h264/1629380139191731149/mda-mhig1c3sw223mx8p.mp4</a></p></li><li><p><a href='http://vd3.bdstatic.com/mda-mekfm7wu6f4rtt99/1080p/cae_h264/1621595318412084671/mda-mekfm7wu6f4rtt99.mp4' target='_blank' class='url'>http://vd3.bdstatic.com/mda-mekfm7wu6f4rtt99/1080p/cae_h264/1621595318412084671/mda-mekfm7wu6f4rtt99.mp4</a></p></li><li><p><a href='http://vd2.bdstatic.com/mda-mesdm11tdp69a9ye/1080p/cae_h264/1622115758783335310/mda-mesdm11tdp69a9ye.mp4' target='_blank' class='url'>http://vd2.bdstatic.com/mda-mesdm11tdp69a9ye/1080p/cae_h264/1622115758783335310/mda-mesdm11tdp69a9ye.mp4</a></p></li></ol><p><span>时间很短的视频文件</span></p><ol start='' ><li><p><a href='https://highlight-video.cdn.bcebos.com/video/6s/95ae2066-ee02-11ed-9f01-6c92bf5ceb6f.mp4' target='_blank' class='url'>https://highlight-video.cdn.bcebos.com/video/6s/95ae2066-ee02-11ed-9f01-6c92bf5ceb6f.mp4</a></p></li><li><p><a href='https://highlight-video.cdn.bcebos.com/video/6s/1a74a352-d1fb-11ed-829b-6c92bf468c1f.mp4' target='_blank' class='url'>https://highlight-video.cdn.bcebos.com/video/6s/1a74a352-d1fb-11ed-829b-6c92bf468c1f.mp4</a></p></li><li><p><a href='https://highlight-video.cdn.bcebos.com/video/6s/e0d35168-edf5-11ed-8709-6c92bf3b0281.mp4' target='_blank' class='url'>https://highlight-video.cdn.bcebos.com/video/6s/e0d35168-edf5-11ed-8709-6c92bf3b0281.mp4</a></p></li><li><p><a href='https://highlight-video.cdn.bcebos.com/video/6s/0757f6ec-ee03-11ed-85d3-6c92bf3b0af4.mp4' target='_blank' class='url'>https://highlight-video.cdn.bcebos.com/video/6s/0757f6ec-ee03-11ed-85d3-6c92bf3b0af4.mp4</a></p></li><li><p><a href='https://highlight-video.cdn.bcebos.com/video/6s/6ffb9cbe-ee01-11ed-916c-6c92bfb45e04.mp4' target='_blank' class='url'>https://highlight-video.cdn.bcebos.com/video/6s/6ffb9cbe-ee01-11ed-916c-6c92bfb45e04.mp4</a></p></li></ol><p><span>专业测试视频播放器的各种文件 </span><a href='http://samples.mplayerhq.hu/' target='_blank' class='url'>http://samples.mplayerhq.hu/</a></p><h4 id='076-网友提供'><span>0.7.6 网友提供</span></h4><p><strong><span>下面的地址几乎都失效</span></strong></p><ol start='' ><li><p><span>rtmp://live.yihtc.com:10935/hls/stream_3</span></p></li><li><p><span>rtmp://live.yihtc.com:10935/hls/stream_13</span></p></li><li><p><span>rtmp://218.3.205.46/live/ggpd_sd</span></p></li><li><p><span>rtmp://hls.hsrtv.cn/hls/hstv2</span></p></li><li><p><span>rtmp://hls.hsrtv.cn/hls/hstv1</span></p></li><li><p><span>rtmp://222.173.22.119:1935/live/jnyd_sd</span></p></li><li><p><span>rtmp://222.173.22.119:1935/live/xwhd_hd</span></p></li><li><p><span>rtmp://livetv.dhtv.cn:1935/live/peoples</span></p></li><li><p><span>rtmp://livetv.dhtv.cn:1935/live/citylife</span></p></li><li><p><span>rtmp://livetv.dhtv.cn:1935/live/financial</span></p></li><li><p><span>rtmp://livetv.dhtv.cn:1935/live/news</span></p></li></ol><h4 id='077-监控设备'><span>0.7.7 监控设备</span></h4><p><strong><span>下面列出的是一些常用厂家的格式，不同厂家格式不一样，具体什么格式请咨询厂家索要对应的视频流格式，或者设备支持onvif的话，通过onvif工具搜索可以拿到视频流格式。</span></strong></p><h5 id='0771-海康'><span>0.7.7.1 海康</span></h5><ul><li><p><span>实时预览格式：rtsp://admin:12345@192.168.1.128:554/Streaming/Channels/101?transportmode=unicast</span></p></li><li><p><span>视频回放格式：rtsp://admin:12345@192.168.1.128:554/Streaming/tracks/101?starttime=20120802t063812z&amp;endtime=20120802t064816z</span></p></li><li><p><span>流媒体视频流：rtsp://172.6.24.15:554/Devicehc8://172.6.22.106:8000:0:0?username=admin&amp;password=12345</span></p></li><li><p><span>日期时间格式：ISO 8601 表示Zulu(GMT) 时间 YYYYMMDD”T”HHmmSS.fraction”Z”，</span></p></li><li><p><span>单播多播说明：unicast表示单播，multicast表示多播，默认单播，可以省略。</span></p></li><li><p><span>通道码流说明：101，1是通道号，01是通道的码流编号，也可以是02、03，第2通道主码流=201，第16通道子码流=1602，依次类推。</span></p></li></ul><h5 id='0772-大华'><span>0.7.7.2 大华</span></h5><ul><li><p><span>实时预览格式：rtsp://192.168.1.128:554/cam/realmonitor?channel=1&amp;subtype=0&amp;unicast=true&amp;proto=Onvif</span></p></li><li><p><span>视频回放格式：rtsp://admin:12345@192.168.1.128:554/cam/playback?channel=1&amp;subtype=0&amp;starttime=2021_03_18_11_36_01&amp;endtime=2021_03_18_12_05_01</span></p></li><li><p><span>格式内容说明：channel表示通道，subtype表示码流编号，日期时间字符串非常明确。</span></p></li></ul><h5 id='0773-常规'><span>0.7.7.3 常规</span></h5><ul><li><p><span>实时预览格式：rtsp://admin:12345@192.168.1.128:554/live?channel=1&amp;stream=1</span></p></li><li><p><span>视频回放格式：rtsp://admin:12345@192.168.1.128:554/file?channel=1&amp;start=1494485280&amp;stop=1494485480</span></p></li><li><p><span>其他通用格式：rtsp://admin:12345@192.168.1.128:554/0  0-主码流 1-子码流</span></p></li><li><p><span>日期时间说明：先转换时间戳，1970年到该时间经过的秒数。</span></p></li></ul><h4 id='078-指定协议'><span>0.7.8 指定协议</span></h4><ul><li><p><span>由于视频流源头限制，可能有些源头只支持tcp/udp协议的一种，就需要手动指定。</span></p></li><li><p><span>指定tcp协议打开视频流：rtsp://admin:12345@192.168.1.128/1|tcp</span></p></li><li><p><span>指定udp协议打开视频流：rtmp://livetv.dhtv.cn:1935/live/financial|udp</span></p></li></ul><h3 id='08-版本说明'><span>0.8 版本说明</span></h3><h4 id='081-精益求精'><span>0.8.1 精益求精</span></h4><p><strong><span>后期规划</span></strong></p><ol start='' ><li><p><span>摄像机信息表的用户信息字段用起来，视频流地址不带用户信息，主动加入用户信息构建最终地址应用。</span></p></li><li><p><span>用户密码密文存储，防止泄露。</span></p></li><li><p><span>重新编码保存模式下，不支持crop裁剪滤镜。</span></p></li></ol><p><strong><span>V20240315</span></strong></p><ol start='' ><li><p><span>修复样式表不支持utf8以及带BOM格式的文件，换成采用QTextStream文本流来读取。之前如果用户在qtcreator中打开样式表修改后保存成了非ANSII格式，导致file.readAll()读取后执行出错，样式表失效。</span></p></li><li><p><span>本地摄像头保存MP4文件增加音频存储，之前由于本地设备音视频存储不同步的问题一直默认去除了音频存储，只有视频存储。近期才发现原来是由于写入的时候调用的av_interleaved_write_frame，默认会缓存，导致可能音频越来越慢。改成av_write_frame即可。</span></p></li><li><p><span>增加保存裸流文件名判断机制，如果设置的强转264，则裸流文件名是h264，如果设置了强转265，则裸流文件名是h265，其他则按照源头是什么格式就对应什么格式。</span></p></li></ol><p><strong><span>V20240305</span></strong></p><ol start='' ><li><p><span>去掉了EncodeType编码策略枚举和对应参数，合并到视频编码枚举参数，EncodeVideo增加EncodeVideo_None枚举。</span></p></li><li><p><span>增加判断文件是否有B帧静态函数。如果是有B帧，则推流的时候建议转码，否则推流后拉流出来的视频很可能是抽搐的。</span></p></li><li><p><span>调整编码策略，现在支持rtsp+pcma/pcmu数据保存到mp4文件，音频不用转码。</span></p></li><li><p><span>视频控件悬浮条录制中字样做了修改，区分是保存到文件还是推流，对应字样 录制中/推流中。</span></p></li><li><p><span>重新调整音视频同步策略。</span></p></li></ol><ul><li><p><span>默认同步；</span></p></li><li><p><span>rtsp视频流默认不同步；</span></p></li><li><p><span>本地设备（本地摄像头和桌面）采集不同步；</span></p></li><li><p><span>设置了最快速度解码则不同步；</span></p></li><li><p><span>设置了质量优先解码则同步；</span></p></li><li><p><span>纯音频永远同步；</span></p></li><li><p><span>这些策略按照优先级从低到高；</span></p></li><li><p><span>比如是视频文件，但是又设置了最快速度解码，则不同步；</span></p></li><li><p><span>比如是rtsp视频流或者本地设备采集，又设置了质量优先解码，则同步；</span></p></li><li><p><span>比如是本地音频文件，设置了最快解码，因为是纯音频，则同步；</span></p></li><li><p><span>视频文件最快速度解码不同步，是为了测试本机的解码性能，一直不停的读取和解码显示。</span></p></li></ul><p><strong><span>V20240205</span></strong></p><ol start='' ><li><p><span>将编码参数合并成编码信息结构体，放到了基类中。</span></p></li><li><p><span>修复内核ffmpeg强制转码保存分辨率不支持奇数的bug。增加了自动调整到偶数的策略。</span></p></li><li><p><span>将ffmpegsave类拆分出来ffmpegsavehelper类，专门存放保存相关的静态函数。</span></p></li><li><p><span>将ffmpegthread类拆分出来ffmpegthreadhelper类，专门存放解码相关的静态函数。</span></p></li><li><p><span>将ffmpeg所有函数接口支持到ffmpeg6，将废弃函数全部换成了新的，自动识别是何种ffmpeg版本自动调用对应的函数接口。对应各种版本不同的函数接口调用都放在ffmpeghelper类中。</span></p></li><li><p><span>保存264/265裸流增加sps/pps信息，保证所有解码出来的流保存成裸流文件都能正确解析。</span></p></li><li><p><span>保存视频文件信号中的文件名参数改成了真实的文件名（之前是传入的文件名/不够准确/因为可能会自动调整到真实的拓展名），比如纯音频文件是wav拓展名，裸流文件是h264/h265拓展名。</span></p></li><li><p><span>保存文件策略中将纯音频的保存统一编码保存到wav文件，保证所有音频格式解码后都能正确保存到wav文件。</span></p></li><li><p><span>保存文件增加了超时回调，防止在推流的时候碰到流媒体服务器不通或者有问题，导致卡主很久。</span></p></li></ol><p><strong><span>V20240125</span></strong></p><ol start='' ><li><p><span>修复无声卡电脑关闭视频的时候崩溃的bug。</span></p></li><li><p><span>修复主界面在注释掉部分停靠窗体后，加载界面可能导致界面索引溢出的bug。</span></p></li><li><p><span>修复倍速播放的时候声音可能产生呲呲声音的bug，采用同步修改采样率，比如采样率44100，倍速2，则音频播放设备采样率=44100乘以2。</span></p></li><li><p><span>内核ffmpeg增加倍速保存，比如60s的文件可以加速编码保存成30s的文件。如果保存的文件存在音频则最大2倍速，仅有视频则倍速可以到8倍。该机制同样适用于推流。</span></p></li><li><p><span>改进音视频同步线程是否启动机制，只有存在视频则启动视频同步，存在音频才启动音频同步。并且都要求开启了音视频同步标志位的情况下启动。</span></p></li><li><p><span>改进音频振幅控件，自动计算宽高绘制振幅，垂直则绘制垂直状的振幅。</span></p></li><li><p><span>第三方录屏screen-capture-recorder，由于不支持设置桌面索引和分辨率，改成从源头修改分辨率和帧率等参数。</span></p></li><li><p><span>修复重连阶段，开启了悬浮音柱的情况下，音柱没有隐藏的bug。</span></p></li><li><p><span>修改绘制背景策略，只要是启动了线程就清空背景，停止了线程就绘制背景。这样可以直观的察觉当前是否已经启动了线程。</span></p></li><li><p><span>音频组件中的音频振幅控件增加渐变颜色。</span></p></li><li><p><span>音频播放组件增加变速不变调处理，采用的sonic库做运算。可以变速不变调，也可以不变速变调，还可以不改变声卡音量的情况下，通过声音数据运算，强制提高音量。</span></p></li><li><p><span>增加通道默认颜色为黑色。之前是透明色。</span></p></li><li><p><span>新增了全景通道布局，放在y布局大类中，就是上下4个通道，中间一个长方形的大通道。</span></p></li></ol><p><strong><span>V20240118</span></strong></p><ol start='' ><li><p><span>轮询期间新增禁止录像策略。停止轮询后恢复设置的状态。</span></p></li><li><p><span>修复轮询视频期间，没有应用声音大小和静音状态的机制。</span></p></li><li><p><span>修复声音大小设置时机可能不准确的bug。</span></p></li><li><p><span>新增打印信息开关，可以控制视频解码线程、保存线程、onvif线程中的打印信息是否开启。</span></p></li><li><p><span>修复在设置了setCodecForLocale编码下，采集指定中文标题的时候可能失败的bug。</span></p></li><li><p><span>增加自适应解码器采集各种本地摄像头设备，优先尝试用mjpeg解码本地摄像头设备，失败后则不指定解码器再重新打开一次。保证任何时候都能正常打开。</span></p></li><li><p><span>新增了devicehelper类，专门用于获取本地视音频输入设备名称集合。</span></p></li><li><p><span>将core_videobase组件拆分成core_videobase/core_videohelper两个组件，将辅助相关的类放到了core_videohelper组件中，分类更精准，更易学习。</span></p></li><li><p><span>批量添加模块增加自动获取本地视音频设备名称，可以指定视音频设备地址添加。</span></p></li><li><p><span>本地设备地址增加解码器名称列，可以直接通过url地址指定是mjpeg/h264/默认值几种解码器来打开设备。</span></p></li></ol><p><strong><span>V20240112</span></strong></p><ol start='' ><li><p><span>去掉1通道0_1标识，改成x布局中增加1_1x1这种万能方式，同时调整主界面底部1通道按钮选中逻辑。</span></p></li><li><p><span>带音柱通道，悬浮音柱模式下，增加判断如果当前视频没有音频，则不显示音柱。</span></p></li><li><p><span>新增音柱背景颜色透明度配置参数，默认全透明=0，0-255范围值。</span></p></li><li><p><span>修复在设备树节点选中的情况下，从本地文件夹拖曳文件播放后，可能出现选中节点也拖曳的的情况。</span></p></li><li><p><span>考虑到视频相关的参数配置越来越多，将视频参数配置单独起一个界面。</span></p></li><li><p><span>新增音柱背景透明度和悬浮条背景透明度值在视频参数配置中，调整后立即应用。</span></p></li><li><p><span>修复在没有开启视频存储的时候，当手动录像期间，到了整半小时（处于0分钟或者30分钟的时候）的时候会被终止录像的bug。</span></p></li><li><p><span>新增mac上获取cpu序列号，用于秘钥文件。</span></p></li><li><p><span>修复开启共享解码线程模式下，地图上点开的视频，会停止采集的bug。这是近期新增的电子放大功能引入的bug，目前策略是除了主界面视频通道窗体外，其他弹出的视频窗体全部不采用共享解码，实际上也只有主界面才需要共享解码线程。</span></p></li><li><p><span>修复频繁大量打开关闭通道可能造成内存泄漏的bug，该bug是Qt本身的bug，qaudiooutput在线程中执行释放不干净，需要进行特殊处理。</span></p></li><li><p><span>声音播放线程增加过滤，没有声音索引的媒体文件，不会启动该线程，之前是默认启动。</span></p></li></ol><p><strong><span>V20240105</span></strong></p><ol start='' ><li><p><span>音频振幅和实时码率改成了立即应用，可以通过基类的视频控件以及视频采集线程设置。这样只在需要统计实时码率的时候才会去真正统计，大大节约CPU运算。</span></p></li><li><p><span>重新调整videobox视频布局盒子类，将changeVideo信号改成changeLayout，更贴切。其他很多函数名和变量也做了对应更改，包括配置参数的videoType改成了layoutType，之前的命名很容易误解成视频类型，其实是为了表示画面布局类型，比如当前1_6通道显示。</span></p></li><li><p><span>将videoUrl改成mediaUrl，VideoType改成MediaType，使得描述更准确，媒体地址可以是视频地址也可以是音频地址等。</span></p></li><li><p><span>将纯音频标志位onlyAudio判断改成了解析中判断，最终解析后只有音频没有视频才认定是纯音频，有些网络视频流也是纯音频，比如m3u8格式的hls流。要最终解析完成后才能判断。</span></p></li><li><p><span>统一约定只有本地mp3文件才需要解析封面并绘制封面。</span></p></li><li><p><span>悬浮条信息增加视频模式，由于不同解析内核会自动调整视频显示的模式，比如设置的绘制，由于该内核不支持绘制，调整成句柄，方便查看最终何种视频展示模式。</span></p></li><li><p><span>统一了本地设备采集包括本地摄像头和桌面采集的url规则，各种视频解析内核通用，调整了对应相关的函数接口逻辑。</span></p></li><li><p><span>修复桌面录屏在ffmpeg5以下版本不支持指定窗口中文标题的BUG，需要转换成toLocal8Bit。</span></p></li><li><p><span>统一设备采集标识Device_Audio/Device_Video/Device_Screen三种。</span></p></li><li><p><span>媒体类型MediaType_Desktop改成MediaType_Screen，描述更准确。同时将桌面采集对应地址前缀desktop=改成screen=。</span></p></li><li><p><span>配置参数增加悬浮条背景透明度，可以通过设置对应的值控制悬浮条的透明度。</span></p></li></ol><p><strong><span>V20240101</span></strong></p><ol start='' ><li><p><span>本地设备采集增加本地音频输入设备采集，现在可以指定 video=USB Video Device:audio=麦克风 (USB Audio Device) 这种格式采集摄像头和音频一起。</span></p></li><li><p><span>增加采集音频参数设置。</span></p></li><li><p><span>增加对 screen-capture-recorder 设备的采集，一个第三方高效录屏库。</span></p></li><li><p><span>使用 screen-capture-recorder 桌面采集的同时可以录制音频。</span></p></li><li><p><span>新增各种保存路径配置参数，可以在其他设置中配置录像文件路径、报警视频路径、抓拍图片路径、报警图片路径。支持中文路径等。</span></p></li><li><p><span>通道报警后，对应抓图或者存储报警视频，按照设置的路径存储，同时存储警情记录到数据库，记录带报警图片或者报警视频的路径，在日志记录查询中可以双击查阅。如果当前触发的报警存储了报警视频则优先取报警视频路径。</span></p></li><li><p><span>本地摄像头采集增加强制设置成mjpeg格式，由于一些小分辨率下默认是rawvideo格式，不支持滤镜，所以换成mjpeg格式都支持滤镜。</span></p></li><li><p><span>悬浮条显示的文本信息，新增了结构体参数，可以设置哪些信息需要显示，比如分辨率、帧率、封装格式、视频解码格式、音频解码格式、实时码率、硬解名称等。默认只开启分辨率显示。</span></p></li><li><p><span>新增配置参数用于配置悬浮条可以显示哪些信息。</span></p></li><li><p><span>功能激活复选框改成放到列表中，方便后期拓展更多可控的激活功能，包括悬浮条哪些参数可以显示。</span></p></li><li><p><span>音柱位置新增上下左右排列等多种布局，可以在系统设置中选择。</span></p></li><li><p><span>删除两个配置参数，音频振幅AudioLevel（用音柱位置参数VolumePosition替换/0表示不启用/&gt;0表示启用），统计实时码率CountKps（用悬浮条参数RealBitRate替换，一旦开启了显示悬浮条码率参数，则必须开启）。</span></p></li><li><p><span>新增音柱尺寸策略，可以选自动设置，也可以设置固定的值，以便适应各种用户需求。</span></p></li><li><p><span>增加纯麦克风采集音频支持，可以指定音频输入设备比如麦克风采集。</span></p></li><li><p><span>音柱位置间隙根据悬浮条位置自动留出间隙，以便悬浮条有足够空间。</span></p></li><li><p><span>系统设置中的视频参数变化，悬浮条位置切换、音柱尺寸等参数变化，改变后立即应用。</span></p></li><li><p><span>音柱尺寸增加用户自定义值，用户可以通过直接修改配置文件指定一个特殊的值。由于下拉框中的值都是一些常规值，用户如果找不到对应的值可以通过修改配置文件更改，对应指定的值也会自动添加到下拉框。</span></p></li><li><p><span>系统设置中各种悬浮条信息配置改成勾选后立即应用。</span></p></li></ol><p><strong><span>V20231205</span></strong></p><ol start='' ><li><p><span>增加通用地址格式规范，url|transport|encodeType|encodeVideo|encodeVideoRatio|encodeVideoScale，可以直接在播放地址中指定通信协议、是否编码保存、编码帧率等信息，具体可以参见说明书中的地址格式说明。</span></p></li><li><p><span>对大华的NVR增加自适应计算配置文件个数，有些是2个有些是3个，需要自适应，计算后按照对应的规则添加NVR的通道。</span></p></li><li><p><span>鼠标拾取限定鼠标左键操作。</span></p></li><li><p><span>悬浮条增加判断，如果处于电子放大期间则鼠标移开不自动隐藏，方便标记当前哪些通道处于电子放大期间。</span></p></li><li><p><span>鼠标画矩形增加坐标换算，鼠标可能是从左上角到右下角，也可能是从右侧到左侧，而QRect只支持左上角右下角参数，需要自动换算，用户有可能是从右下角到左上角，这些特殊情况也要支持。</span></p></li><li><p><span>新增切换声卡接口，已经实现了qmedia、vlc、mpv、ffmpeg等内核对应切换声卡接口。有些用户希望每个通道可以指定到不同的声卡来播放声音。</span></p></li><li><p><span>通道布局类重新调整接口，将2通道和3通道布局移动到x布局中，同时增加自定义x布局接口函数，比如可以手动指定3x6布局这种，非常灵活，方便垂直屏幕展示。</span></p></li><li><p><span>新增自定义y布局，之前自定义x布局专门是固定行列数的布局，可以自行添加，将一些特殊定制的布局放在自定义y布局中，同时调整诸多函数接口。</span></p></li></ol><p><strong><span>V20231125</span></strong></p><ol start='' ><li><p><span>视频监控布局类videobox新增了指定行数列数接口，新增了指定行列数的默认布局，比如1_2x4表示通道1开始按照2行4列排列，方便垂直屏幕展示比如手机上或者竖屏。</span></p></li><li><p><span>优化本地摄像头和桌面采集的暂停策略，和文件一样，暂停期间不需要去实时采集。而视频流这种暂停期间必须实时采集不解码。</span></p></li><li><p><span>修复http地址中带空格的地址无法正常播放的BUG，需要用QUrl().toEncoded转码。</span></p></li><li><p><span>鼠标按下发送对应源图像坐标信号增加事件类型参数，鼠标按下、鼠标松开、鼠标移动三种都能够发出信号，以便外部用于动态绘制矩形区域，相当于拿到对应的矩形区域在下发处理。</span></p></li><li><p><span>内核增加电子放大功能，鼠标按下拾取区域，作为crop滤镜，实现电子放大。移除该滤镜可以恢复。</span></p></li><li><p><span>屏幕采集增加自定义区域采集规则，约定屏幕索引255则取用户填入的自定义区域进行采集。</span></p></li><li><p><span>组件onvif增加错误数据返回信号，可以查看具体错误数据信息，方便分析问题，比如是否是用户信息不对导致的。</span></p></li><li><p><span>悬浮条增加电子放大按钮，直接开启电子放大和结束电子放大，电子放大期间，在视频画面上选择区域后自动对该区域放大。</span></p></li></ol><p><strong><span>V20231105</span></strong></p><ol start='' ><li><p><span>内核ffmpeg中保存类型SaveVideoType_H264改成了SaveVideoType_Stream，表示裸流类型，可以是264/265。</span></p></li><li><p><span>保存裸流情况下增加区分264/265拓展名。</span></p></li><li><p><span>内核ffmpeg/qtav/easyplayer/海康sdk等增加逐帧播放功能。</span></p></li><li><p><span>内核ffmpeg增加缓存大小的参数传入，对应buffer_size参数，可以通过参数配置。有些极大帧率或者分辨率的设备需要这个参数设置才能正常运行，否则很可能缓存不够导致花屏。</span></p></li><li><p><span>修正onvif组件在设备没有回传时区TimeZone节点信息的时候无法正确设置时间的BUG，改成默认用东八区去计算。</span></p></li></ol><p><strong><span>V20231010</span></strong></p><ol start='' ><li><p><span>修复部分视频文件在循环播放的时候失效的BUG，经查阅这种文件一般前面会缺失一些数据帧，导致播放定位失败，改成通过videofirstpts时间判断。</span></p></li><li><p><span>修复在win10及以上系统中CPU使用率采集和任务管理器不一致的BUG，改成了命令行typeperf获取。</span></p></li><li><p><span>修复了ffmpeg内核opengl绘制yuv数据在部分很老的硬件上绿屏的BUG，将 GL_RED 全部换成了 GL_LUMINANCE 以便支持旧版本的opengl。比如部分配置低的手机。</span></p></li><li><p><span>修复linux系统上采集本地摄像头无法设置分辨率的BUG。</span></p></li><li><p><span>本地文件回放增加拖曳播放，方便用于测试从NVR下载的视频文件。</span></p></li><li><p><span>内核ffmpeg增加自动获取本地音视频设备文件名的接口。</span></p></li></ol><p><strong><span>V20230915</span></strong></p><ol start='' ><li><p><span>彻底解决应用滤镜后可能出现崩溃的BUG，比如在频繁大量切换新的滤镜过程中，刚好界面这边在绘制画面数据，导致数据冲突引发的BUG，之前绘制模式和硬解码模式不崩溃是因为，绘制模式用的是painter绘制图片，没有用opengl绘制，硬解码是因为取出来的帧数据就是中转过的，不会出现数据冲突的情况。所以在没有硬解码情况下的opengl绘制模式，增加了一个avframe用于中转数据，同时在新切换滤镜后的延迟1-2帧（时间大概0.03s）应用新的滤镜，这样就再也不会出现opengl绘制数据冲突崩溃情况。也考虑过传递给opengl绘制的数据拷贝一份，肯定可以终极解决问题，但是每次帧数据都拷贝一份那就增加了不少CPU，不可取。</span></p></li><li><p><span>将录播监控类型去掉，配置参数新增了AudioLevel用于开启音频振幅，开启后，主界面每个通道右侧会显示对应的音频振幅，分左右通道。</span></p></li><li><p><span>桌面采集改成永远不共享解码策略。</span></p></li><li><p><span>新增摄像机和录像机默认名称配置参数。</span></p></li><li><p><span>双击NVR父节点打开该节点下面的所有摄像机，增加延时，防止不延时情况下在部分电脑上可能崩溃的BUG。</span></p></li></ol><p><strong><span>V20230906</span></strong></p><ol start='' ><li><p><span>修复本地桌面地址默认分辨率问题，当没有指定分辨率的时候取当前鼠标所在的屏幕区域作为分辨率。支持多屏幕，包括虚拟机中分辨率奇数问题，自动取偶数。</span></p></li><li><p><span>重新调整桌面录屏的XY坐标策略，设置值永远是正数值，根据当前屏幕所在位置进行偏移（左上角X=0 Y=0），多屏幕情况下坐标可能是负数，而且屏幕可以是横向还可能是竖向，自动程序计算，这样用户只需要填入从当前屏幕左上角开始偏移多少就行，而不需要去计算具体的值。同时纠正超过屏幕区域的采集分辨率，以设定的偏移值开始到右下角结束进行裁剪。</span></p></li><li><p><span>桌面采集增加手动支持屏幕索引参数，在XY坐标偏移值后面，不指定则以鼠标所在当前屏幕为准，指定则以指定的索引为准，屏幕索引大于屏幕数量则以鼠标所在当前屏幕为准。这样相当于可以对每个屏幕分开采集，每个屏幕都是在一个独立的通道显示。</span></p></li><li><p><span>测试发现在linux系统上如果使用ffmpeg静态库，会报错提示avfilter不成功，需要调整库链接顺序才行，之前是 -lavformat -lavcodec -lavfilter -lswscale -lavutil -lswresample，统一改成 -lavformat -lavfilter -lavcodec -lswresample -lswscale -lavutil ，通过查阅ffmpeg的示例代码的链接顺序得知。</span></p></li><li><p><span>测试发现在ubuntu18/20/22等系统上编译程序设置rpath失败，导致编译后的程序只能编译运行，不能双击运行。查阅资料原来是新版的系统修改了对应的rpath设置机制，</span><a href='https://blog.csdn.net/random_repick/article/details/122980119'><span>https://blog.csdn.net/random_repick/article/details/122980119</span></a><span> ，需要在编译参数加上 -disable-new-dtags 参数即可。之前是 QMAKE_LFLAGS += &quot;-Wl,-rpath,</span><span>&#39;</span><span>$</span><span>$ORIGIN/lib</span><span>&#39;</span><span>&quot; ，改成 QMAKE_LFLAGS += &quot;-Wl,-rpath,</span><span>&#39;</span><span>$</span><span>$ORIGIN/lib</span><span>&#39;</span><span>,-disable-new-dtags&quot; 。</span></p></li><li><p><span>滤镜osd增加了背景颜色参数，支持透明度。</span></p></li><li><p><span>修正linux系统桌面采集对应偏移值没起作用的BUG，需要通过设备名传入，比如 :0.0+0,0 后面的 0,0 才是表示偏移值。</span></p></li></ol><p><strong><span>V20230818</span></strong></p><ol start='' ><li><p><span>所有密码框全部提升为自定义文本框控件，全局样式加入密码按钮，单击显示密码，再次单击密文显示。登录窗体、登出窗体、数据库管理等界面。</span></p></li><li><p><span>数据库组件增加access数据库的支持。</span></p></li><li><p><span>通过远程设备回放rtsp视频流，增加进度条显示，可以切换进度条，一般海康大华等厂家的NVR支持rtsp视频流回放，而且带了时长，可以切换回放的进度，但是不能倍速。</span></p></li><li><p><span>将带柱状声音条的视频面板重命名为 frmvideowidgetvolume，带播放进度条和时长的视频面板命名为 frmvideowidgetslider，视频预览窗体重命名为 frmvideowidgetpreview，因为这三者属于独立的视频控件窗体，在多处独立使用。</span></p></li><li><p><span>远程回放rtsp视频流增加同步播放进度，勾选后，切换某个通道进度，其他几个通道自动切换到对应播放进度，这样可以查看回放通道同一时刻的监控画面。</span></p></li><li><p><span>更新地图秘钥，之前的秘钥文件由于使用者太多，会出现未授权地图字样。</span></p></li><li><p><span>修复onvif报警事件触发的报警录像存储文件前缀标识不正确的BUG，当通道显示的主码流而系统设置默认打开子码流的情况下会发生。</span></p></li><li><p><span>日志记录中备注字段用于存储报警图片文件或者报警视频文件的文件名称，报警视频优先级大于报警图片。双击预览报警图片或者报警视频。</span></p></li><li><p><span>修复报警日志中弹出预览失败的情况，当文件被删除后要先判断文件是否存在。</span></p></li><li><p><span>回放界面增加了播放按钮，可以暂停和继续播放当前回放的视频。</span></p></li><li><p><span>将报警视频预览单独一个函数，带播放进度条，回放报警时候的时候，可以暂停和继续播放。</span></p></li><li><p><span>日志记录增加按照通道查询。报警日志存入的时候都统一换成两位字符串作为通道存入，比如 01/02/03/16，统一长度对齐。</span></p></li><li><p><span>修复实时视频流查看的时候，没有时长的BUG，不要去获取时长，是个很大的负数。只有回放的视频流才有时长。</span></p></li></ol><p><strong><span>V20230802</span></strong></p><ol start='' ><li><p><span>轮询管理中添加轮询通道的时候，对应分组以右侧选中的分组为准，选中的哪个分组则对应添加的时候就添加到对应轮询分组中。</span></p></li><li><p><span>轮询管理中左侧表格增加右键菜单（全部选中、反向选中、全部不选），执行对应的操作。</span></p></li><li><p><span>增加自定义密码文本框，可设置双击显示明文/失去焦点自动恢复，以及右侧显示密码按钮，单击切换明文密文显示。</span></p></li><li><p><span>修复ffmpeg内核录像阶段硬解码模式下各种滤镜信息没有保存到文件的BUG。</span></p></li><li><p><span>修复ffmpeg内核录像阶段硬解码模式下保存的视频文件，播放期间渐渐变模糊的BUG。</span></p></li><li><p><span>core_qui组件更名为core_qthelper，里面的类名也全部重新更换，比如quihelper改成了qthelper，表达更精确。</span></p></li><li><p><span>内核ffmpeg增加视频流地址末尾加通信协议(tcp/udp)，有些视频流必须用tcp或udp协议才能加载成功，可以手动指定，已经有全局的视频配置参数，地址中带的协议优先级最高，没有带则采用全局配置的。</span></p></li><li><p><span>彻底解决时区时间不对导致部分摄像头设备不能onvif交互的问题，如果本地时区设置的和设备设置的时区不一致，需要转换后再统一用标准时间去下发onvif指令，之前写死的东八区8小时，应该根据系统环境去获取，而且还要区分夏令时（时区-1），还要区分半小时制的时区（5.30时区），一套组合拳打下来，彻底解决问题。嵌入式板子很多不是东八区或者linux系统也可能是其他时区。</span><strong><span>这个细节市面上99%的onvif协议监控软件都没有考虑（一运行就崩溃或者无法正常加载onvif设备），必须要求运行软件的环境和设备所在环境的时区时间一致。</span></strong></p></li></ol><p><strong><span>V20230718</span></strong></p><ol start='' ><li><p><span>各种内核都增加音视频轨道参数，可以读取和设置，在节目流ts文件非常有用，可以手动指定音视频轨道。</span></p></li><li><p><span>通信协议增加none选项，有些rtsp视频流不支持设置tcp/udp通信参数。</span></p></li><li><p><span>内核ffmpeg增加设置旋转角度功能，比如现场传过来的原视频是倒的，可以主动设置旋转角度旋转成正的，而且保存视频文件也可以一起应用这个设置。</span></p></li><li><p><span>修复大分辨率视频采用GPU绘制模式开启大量滤镜下可能崩溃的BUG。频繁更新滤镜，会和opengl绘制冲突，如果是painter绘制，不影响。如果采用硬解码，也没有这个问题。</span></p></li><li><p><span>重写云台仪表盘控件，在现有换肤下更精美，新增了边距和渐变边框等属性，修复了鼠标按下时候可能崩溃的BUG。</span></p></li><li><p><span>新增配置参数控制是否通道名字用摄像头的名字，默认通道01/通道02字样。</span></p></li><li><p><span>配置参数增加公司网址/公司电话，可以自定义，在弹出关于对话框中显示。</span></p></li><li><p><span>修复当设备树状列表不开启码流子节点的时候，左侧通道选中，设备列表选中节点不正确的BUG。</span></p></li><li><p><span>将标签信息停靠窗体改成按钮弹出来，不放在主界面悬停窗体组合中。</span></p></li><li><p><span>新增网络信息配置窗体，用于查询和修改设备的网络信息比如IP地址子网掩码等。</span></p></li></ol><p><strong><span>V20230705</span></strong></p><ol start='' ><li><p><span>增加265裸流文件的正常解析。</span></p></li><li><p><span>去掉串口模块的依赖，备用，有些msvc套件编译这个模块会报错。</span></p></li><li><p><span>增加两个开关，顶部标题右键菜单和悬停模块右键菜单，可以在系统设置中勾选开启。</span></p></li><li><p><span>增加了2/3分屏显示。可选择是否启用，默认关闭。</span></p></li><li><p><span>修复当单独使用解码线程类（没有视频显示窗体）的时候，无法正常关闭的BUG。因为之前不存在单独使用解码线程类。</span></p></li><li><p><span>内核ffmpeg保存视频增加指定分辨率和缩放比，这样可以大大减少文件体积，比如显示采用1920x1080分辨率，保存采用640x480，还可以指定等比例缩放比，比如0.5缩放比则是等比例减少一半，保持宽高等比例。</span></p></li><li><p><span>内核ffmpeg保存视频增加仅仅发送数据包标志位，这样可以在保存的时候进行多路推流和保存到其他文件。也就是打开一个视频地址可以保存到多个不同的文件或者推流到多路。</span></p></li><li><p><span>视频监控增加打开失败信号，参数对应错误枚举值，可以对应查看枚举值定义找出具体错误原因。</span></p></li><li><p><span>内核ffmpeg视频保存类在推流模式下增加自动重连机制，流媒体服务器中断恢复后自动重连继续推流。</span></p></li><li><p><span>内核ffmpeg视频保存类增加保存开始/保存结束/保存失败信号，方便推流的时候根据信号做出反应。</span></p></li><li><p><span>修复多屏幕在上下屏情况下右下角弹出框位置不正确的BUG，此问题N多知名软件也存在，可能上下屏的用户情况比较少。</span></p></li><li><p><span>增加了云台移动类型下拉框，默认隐藏，可以配置文件VisiblePtzStep打开，可选绝对移动/相对移动/连续移动，默认连续移动，所有厂家都会实现连续移动，大部分厂家未实现其他两种移动。</span></p></li></ol><p><strong><span>V20230611</span></strong></p><ol start='' ><li><p><span>增强解码的健壮性，比如在ffmpeg中未找到对应的解码器，取消对应视音频的处理，比如没找到G.722.1的音频解码器（AV_CODEC_ID_NONE），则不处理音频数据，直接保留处理视频数据即可。之前是直接打开失败不做任何处理。</span></p></li><li><p><span>内核ffmpeg增加了清空缓存接口，在切换播放进度前执行。测试发现有极少数文件切换进度后存在缓存数据导致画面发抖1-2s。</span></p></li><li><p><span>滤镜初始化增加锁，防止大量通道启用大量滤镜，界面切换和尺寸发生变化的时候导致的可能崩溃的BUG。</span></p></li><li><p><span>设备播放模块增加自动自增通道号功能，一般从NVR打开1路以后接下来就是打开第二路，递增即可。</span></p></li><li><p><span>修复带旋转角度的视频在绘制模式以及抓图下画面不正确的BUG。</span></p></li><li><p><span>onvif组件修复当rtsp端口不是554的时候的地址获取错误的BUG，统一调整即支持外网映射交互整个onvif组件，也支持内网包括修改过端口的。</span></p></li><li><p><span>将filehttp改成fileweb类型，因为rtsp视频流也有时长的时候，有些回放视频流是rtsp格式带了时长，可以任意切换播放位置。</span></p></li><li><p><span>增加删除和修改摄像机信息后，视频通道对应更新状态，比如删除了某个设备，该设备如果处于播放阶段则停止播放。</span></p></li></ol><p><strong><span>V20230605</span></strong></p><ol start='' ><li><p><span>内核ffmpeg保存视频类增加超时判断。</span></p></li><li><p><span>内核ffmpeg所有类打印错误信息参数增加带上错误码和错误详情，方便分析问题。</span></p></li><li><p><span>内核ffmpeg改进硬解码格式的合法性检查。</span></p></li><li><p><span>修复默认传入静音状态除了ffmpeg内核外其他内核没有生效的BUG。</span></p></li><li><p><span>标签文字水印增加了图形字体的支持，极大的丰富了文字水印的内容，可以将各种图形图案以文字的形式绘制到原图中。文本绘制的性能比图片高很多，可以将方框等各种图形转换成图形字体再以水印加到原图中。</span></p></li><li><p><span>内核ffmpeg增加硬解码失败自动转软解码策略。</span></p></li><li><p><span>内核ffmpeg增加图片滤镜功能，和之前各种文字水印和其他滤镜一起（文字水印和图片水印叠加功能折腾很久）。</span></p></li><li><p><span>重写保存视频线程，支持音视频同步合并保存到MP4文件，保存线程可选是否强制编码还是源数据保存。强制编码会增加CPU占用，但是有些情况必须强制编码，比如非264格式需要推流，重新改变保存文件体积大小，将OSD标签和图形信息存入文件或推流等。</span></p></li><li><p><span>内核ffmpeg保存视频支持不编码（源头是h264/h265+aac）、部分编码（参数指定视频或者音频编码）、完全编码（所有格式不符合则强制编码）等三种组合。</span></p></li><li><p><span>修复如果文件名称为rtmp/rtsp/http开头的时候地址类型解析不正确的BUG，要用rtmp://这种开头判断。</span></p></li><li><p><span>内核ffmpeg增加编码策略选项，可选自动（非264/265/aac则转码）、仅限文件（文件类型则转码）、所有转码，默认选择自动处理，可以大大节约CPU资源占用。</span></p></li><li><p><span>改进策略当选择最快速度播放的时候，文件类型的也全力解码数据并显示，不做任何的同步和延时。这样可以测试本机最大的解码能力。</span></p></li></ol><p><strong><span>V20230522</span></strong></p><ol start='' ><li><p><span>组件onvif增加时间差值计算，有些设备在发送鉴权数据的时候需要以设备的时间为准，而不是以onvif客户端为准，很多设备可能时间在1970年或者2000年，意味着发送鉴权的时候对应时间要1970年或者2000年，不然会鉴权失败，所以在首次鉴权的时候需要获取设备的时间（主动设置时间后也需要获取一次），计算时间差值，下发鉴权的时候主动加上这个差值。</span></p></li><li><p><span>内核ffmpeg增加对指定窗口标题的窗口进行录屏，目前测试下来只支持英文的标题。</span></p></li><li><p><span>修复短时长（5s）视频文件播放在关闭的时候可能崩溃的BUG。</span></p></li><li><p><span>保存视频文件增加首帧必须关键帧的过滤，保证保存的视频文件在任何地方打开都不会绿屏。这个过滤机制会导致保存的视频文件缺少开始部分的帧，比如摄像头设置的I帧（关键帧）间隔是50则最大可能接近2s的帧丢失，这个丢失无法避免，因为开头部分的非关键帧无法正确计算得到完整的图片。</span></p></li><li><p><span>修复了开启了录像计划下，双击打开父节点视频后，录像计划线程停止后未开启的BUG。</span></p></li><li><p><span>视频回放查询功能增加过滤正在写入的文件，不要放入到文件列表。</span></p></li><li><p><span>修复部分265编码的视频流保存的时候时长不正确的BUG，因为视频流有平均帧率和基本帧率，保存的时候取基本帧率。</span></p></li><li><p><span>配置参数增加opengl类型选择，可选AA_UseOpenGLES防止有些电脑显卡驱动版本不够或者硬件显卡不支持的情况，启用AA_UseOpenGLES以后也可以正常使用opengl用来绘制视频数据。</span></p></li><li><p><span>增加用户没有填经纬度时自动以地图中心坐标为准的处理，防止没有经纬度坐标导致地图加载失败。</span></p></li><li><p><span>增加低分辨率下默认隐藏OSD标签管理悬停模块，该模块对界面高度有要求导致把整个界面撑起来而看不到底部。</span></p></li></ol><p><strong><span>V20230510</span></strong></p><ol start='' ><li><p><span>增加文字水印单独示例，专门演示如何添加日期时间标签，文字标签，指定标签更新内容，以及显示实时码率文字水印。</span></p></li><li><p><span>内核ffmpeg增加实时码率计算，发出结果信号。</span></p></li><li><p><span>增加了OSD标签格式日期时间带毫秒枚举值。</span></p></li><li><p><span>增加统计实时码率开关，开启后，在人工智能开关开启状态下，会将实时码率信息以文字水印OSD的方式贴到视频上。</span></p></li><li><p><span>文字水印演示字体大小改成了以视频宽度比例为准，以便保证字体足够大能够看清。</span></p></li><li><p><span>内核ffmpeg增加保存视频压缩比率参数，可根据网络带宽需求调整清晰度，包括保存的视频文件大小和推流占用带宽。</span></p></li><li><p><span>增加保存视频压缩比率参数，可控保存后视频文件体积大小（只针对需要重新编码的场景）。</span></p></li><li><p><span>增加多镜头多通道摄像机的支持，有些摄像机带了多个镜头，每个镜头对应一个通道。</span></p></li><li><p><span>内核ffmpeg增加只推流的情况下手动切换实时预览（需要解码才能预览/推流不需要解码也可以推流/以便最小占用CPU）。</span></p></li></ol><p><strong><span>V20230416</span></strong></p><ol start='' ><li><p><span>新增桌面录屏的支持，包括ffmpeg、vlc、qtav、easyplayer等内核。</span></p></li><li><p><span>桌面录屏可指定录屏区域位置。</span></p></li><li><p><span>完善easyplayer内核对各种视频流的支持。</span></p></li><li><p><span>重新优化视频类型的判断，http开头的地址可能是文件也可能是视频流，以最终时长作为判断依据。</span></p></li><li><p><span>增加了H264裸流视频文件倍速播放。</span></p></li><li><p><span>内核ffmpeg增加发送packet帧信号，一般用于推流的同时保存视频文件需要。</span></p></li><li><p><span>模块onvif增加osd相关处理，可以获取所有osd，并执行添加、删除、修改操作。</span></p></li><li><p><span>增加OSD管理悬停模块，可以增删改查OSD相关信息。</span></p></li></ol><p><strong><span>V20230323</span></strong></p><ol start='' ><li><p><span>onvif模块增加获取mac地址。</span></p></li><li><p><span>所有监控内核增加矫正视频类型，比如http开头的有文件长度的则强制设置为filehttp类型，方便后期其他判断处理。</span></p></li><li><p><span>新增主动设置文件时长和播放进度的函数，以便事件回调那边主动设置。</span></p></li><li><p><span>修复ffmpeg内核部分视频文件当分辨率不是常规分辨率时（比如分辨率426x240）回调取出图片不正确的BUG，转换需要做字节对齐设置，现在约定统一用4字节对齐，这样兼容了所有可能的分辨率。</span></p></li><li><p><span>修复ffmpeg内核在高倍速比如5倍速播放情况下，如果解码来不及导致播放进度计算不正确的BUG。</span></p></li><li><p><span>增加对http开头的地址对应视频类型的判断，有些是视频文件（有时长并且可以切换播放进度），有些是实时视频，尽管地址格式都是 </span><a href='http://xxxxxx/xx.m3u8' target='_blank' class='url'>http://xxxxxx/xx.m3u8</a><span> 这种。</span></p></li></ol><p><strong><span>V20230201</span></strong></p><ol start='' ><li><p><span>新增天气预报模块开关。</span></p></li><li><p><span>海康内核增加手动指定端口解析。</span></p></li><li><p><span>更新onvif相关处理，支持内网摄像头通过路由器端口映射公开到外网，以外网的IP地址形式访问。</span></p></li><li><p><span>设备搜索模块在单播的时候增加厂家为空则先获取设备信息获取到制造商名称并自动填入。</span></p></li><li><p><span>内核vlc增加图片和文字水印功能，从源头处理。</span></p></li><li><p><span>内核mpv增加文字水印功能。</span></p></li><li><p><span>内核ffmpeg增加网络访问视频文件头部消息user_agent=Mozilla，有些视频网站根据这个头部消息过滤不让ffmpeg访问。</span></p></li><li><p><span>onvif单播搜索增加指定地址不存在的过滤。</span></p></li><li><p><span>增加对显卡禁用环境的识别，自动切换采用Qt::AA_UseOpenGLES，否则在禁用显卡环境中无法正常使用opengl。</span></p></li><li><p><span>增加当处于OpenGLES绘制下自动将硬解码改成none，防止无法正常显示视频画面。</span></p></li><li><p><span>onvif组件搜索功能增加错误提示，比如绑定组播失败、单播地址不通等提示。</span></p></li><li><p><span>无人机移动演示模块增加过滤，还没有初始化好就不触发js交互。</span></p></li><li><p><span>增加对虚拟机环境的识别，自动切换采用Qt::AA_UseOpenGLES，否则在虚拟机中硬解码下无法使用AA_UseDesktopOpenGL。</span></p></li><li><p><span>录像计划批量按钮增加先清空再批量，否则通道数不一致。</span></p></li><li><p><span>本地回放等界面增加全选、全不选按钮，用于对查询出来的视频文件全部选中和不选中。</span></p></li><li><p><span>打包文件增加了wenquanyi.ttf字体文件，由于ffmpeg用到了滤镜，为了支持中文正确显示，依赖指定的中文字体文件，放到可执行文件同一目录即可。</span></p></li></ol><p><strong><span>V20230108</span></strong></p><ol start='' ><li><p><span>内核ffmpeg实现了各种OSD标签和图形直接绘制到帧上，保存也带了对应的标签信息，之前是绘制在遮罩层上。</span></p></li><li><p><span>内核ffmpeg带旋转角度的视频旋转采用滤镜实现，之前是通过算法转换。</span></p></li><li><p><span>修复图文警情在清空后重新添加警情的时候最底部一个item可能高度不对的BUG。</span></p></li><li><p><span>批量添加NVR通道改进编号和摄像头名称策略，编号为NVR地址的后两个网段的值加上3位通道字符串，名称为通道001/通道002依次下去。这样符合现场跨网段的场景，一般现场有N多摄像机和NVR，很多都是跨网段的场景。</span></p></li><li><p><span>地图上设备单击弹出视频预览增加过滤，限制双击只允许单击。</span></p></li><li><p><span>增加配置参数控制设备树是否显示主码流子码流节点。</span></p></li><li><p><span>增加配置参数双击打开分组最大数量，0-最大通道数量 1-当前通道数量 2-自动调整数量。</span></p></li><li><p><span>增加配置参数记录最后展开的设备节点，下次打开自动应用。</span></p></li></ol><p><strong><span>V20221212</span></strong></p><ol start='' ><li><p><span>改进实时监测设备在线情况逻辑，之前是一次性所有的处理，改成了排队处理，每次间隔0.1s，同时处理完一个来回后休息5s，这样在设备数据很多的时候尤其有效。</span></p></li><li><p><span>视频参数设置中新增离线检测开关和报警视频存储时间下拉框选择。</span></p></li><li><p><span>设备播放模块增加添加完一个通道后自动切换到下一个通道。</span></p></li><li><p><span>将批量添加单独做成窗体，通用于轮询管理和摄像机管理，可以很方便的批量添加摄像机，录像机通道递增等各种智能规则。</span></p></li><li><p><span>打开弹窗视频增加在线判断，没有开启在线检测则先检测再判断是否需要弹窗。</span></p></li><li><p><span>纠正图片参数调节中饱和度和对比度界面上名称标识写反了的BUG。</span></p></li></ol><p><strong><span>V20221207</span></strong></p><ol start='' ><li><p><span>报警事件抓图后添加到图文警情，改成线程排队处理，之前在主线程处理，如果有多个同时，很可能卡主界面，而且还要等待抓图的文件生成才能正确显示图片。</span></p></li><li><p><span>新增警情字典表config/event.txt，格式 1,IsMotion,移动报警,移动结束 ，分别表示 事件等级/唯一标识/报警字样/解除字样 ，这样大大增强灵活性，每个不同厂家的设备可能有不同的关键字表示不同的警情，用户只需要在字典表中编辑好即可。</span></p></li><li><p><span>内核vlc彻底解决回调模式下视频流需要手动指定的问题，改成了在播放后拿到分辨率后去设置回调数据，完美解决。</span></p></li><li><p><span>修复内核vlc中打开视频流后多次触发读取媒体信息的BUG，包括中途视频流发生变化也会多次触发。</span></p></li><li><p><span>修复悬停模块透明度值应用不及时的BUG。</span></p></li><li><p><span>图文警情双击显示原图增加自适应图片大小策略，并限定最大分辨率。</span></p></li><li><p><span>增加了左右通道音频振幅分别计算，之前混在一起计算。单通道的则左右一样。</span></p></li><li><p><span>视频预览窗体增加自适应视频大小策略，并限定最大分辨率。</span></p></li><li><p><span>新增将选择的软件图标作为全局的左上角图标，选择后立即应用。</span></p></li><li><p><span>修复在共享解码线程中再次打开弹出的视频窗体声音大小和静音状态不一致的BUG，改成了和原共享解码线程一致。</span></p></li><li><p><span>弹出窗体自适应最大尺寸，如果视频尺寸超过了最大尺寸则等比例缩放到合适尺寸。</span></p></li><li><p><span>报警事件抓图按照日期文件夹存放，之前存放在image_alarm目录下挤在一起，多了就很难看。</span></p></li><li><p><span>新增每个视频控件都有共享解码属性，每个控件都可以控制是否需要共享解码，之前是统一全局的属性，有时候需要单独弹出的报警视频独立处理以及存储录像，此时就需要指定该控件不共享解码，极大的增加了自由度。</span></p></li><li><p><span>修复清空录像机信息后，设备列表无法正常加载的BUG，改成了自动生成一个默认的分组。</span></p></li><li><p><span>新增半透明轮询分组提示标签窗体，在轮询启动后显示停止轮询后隐藏，可以拖动到合适位置，自动记忆最后的位置。方便在全屏轮询阶段告知用户当前轮询到哪里。</span></p></li><li><p><span>增加开关量报警弹出报警视频，并录像存储，可在视频回放中查询对应的报警视频并回放。</span></p></li><li><p><span>报警视频弹窗窗体标题栏，如果指定了存储报警录像，则显示关闭倒计时字样。</span></p></li><li><p><span>修复在打开了未连接的视频通道，通道处于不断重连中，单击轮询崩溃的BUG。</span></p></li><li><p><span>onvif组件增加唯一标识，打印信息更清晰，带上唯一标识和设备IP地址。</span></p></li></ol><p><strong><span>V20221125</span></strong></p><ol start='' ><li><p><span>onvif搜索增加超时时间参数，经过大量的现场应用反馈，少部分厂家的设备，在极端的网络环境中，返回的数据要慢，需要把之前写死在代码中的超时时间放出来作为参数设置可调节。</span></p></li><li><p><span>视频参数增加悬浮工具栏位置参数，可以设置视频控件的悬浮条位置在顶部、底部、左侧、右侧四个位置。</span></p></li><li><p><span>解决Qt6.4及以后版本比如Qt6.5上minibink和opengl冲突导致opengl黑屏的bug，此问题找了很久发现原来是和miniblink冲突了，改成了异步加载miniblink浏览器控件即可，代码 QMetaObject::invokeMethod(this, &quot;initWebView&quot;, Qt::QueuedConnection);</span></p></li><li><p><span>对不启用任何解码内核增加过滤，没有指定内核则不用启动解码线程。</span></p></li><li><p><span>测试发现Qt6.4.1版本音频播放有问题，会打印 qt.multimedia.audiooutput: Failed to setup resampler ，确认过是官方新增的bug（</span><a href='https://forum.qt.io/topic/140523/qt-6-x-error-message-qt-multimedia-audiooutput-failed-to-setup-resampler/5' target='_blank' class='url'>https://forum.qt.io/topic/140523/qt-6-x-error-message-qt-multimedia-audiooutput-failed-to-setup-resampler/5</a><span>），用最新的6.5版本即可，总之不要用6.4.1。</span></p></li><li><p><span>使用示例增加音频频谱示例。</span></p></li><li><p><span>使用示例增加拖曳播放示例。</span></p></li><li><p><span>系统设置增加音频振幅开关，开启后视频右侧都会显示左右通道额音量条。</span></p></li><li><p><span>初始化结构体参数增加过滤机制，地址为空的不处理。</span></p></li><li><p><span>新增了视频通道拖动配置参数，可控是否允许拖动交换通道，防止误操作。</span></p></li><li><p><span>增加根据视频控件的高度自动调整音量条格子数量，比如4通道60个格子，64通道20个格子，保证音量条自适应。</span></p></li><li><p><span>音量条的圆角角度、格子高度、边距、间距等参数可自由设置。</span></p></li><li><p><span>静音状态约定只是声音不发送给音频输出设备播放，音频数据正常解析，包括音频频谱正常显示。</span></p></li><li><p><span>增加根据视频控件的宽度自动调整音量条的宽度，比如4通道的时候音量条可以宽一些，64通道音量条可以窄一些。以便留出更多的空间给视频显示而不会显得很拥挤。</span></p></li><li><p><span>增加根据视频控件的宽度自动设置悬浮条提示信息是否需要显示，宽度不够则不显示，比如悬浮条设定显示在左侧右侧由于宽度不够也不显示提示文字信息。</span></p></li><li><p><span>增加报警事件抓图显示在图文警情中。</span></p></li><li><p><span>增加udp://开头的视频流强制采用udp协议解析。</span></p></li><li><p><span>修复重连后默认的音量大小以及静音状态不正确的BUG。</span></p></li></ol><p><strong><span>V20221121</span></strong></p><ol start='' ><li><p><span>新增图形字体文件可编辑，可以根据需要添加自己的图标到iconfont.ttf字体文件，需要借助fontcreator工具。</span></p></li><li><p><span>新增部分图标，把底部通道1-通道64的图标换成了数字模样的，整齐统一容易拓展。</span></p></li><li><p><span>修复ffmpeg内核声音播放的时候遇到标题栏或者UI按下卡住停顿0.5s的BUG，改成了线程中播放音频，无论UI如何卡丝毫不影响。</span></p></li><li><p><span>视频回放增加手动停止按钮以及静音切换按钮。</span></p></li><li><p><span>增加ffmpeg内核声音解码过滤，部分摄像机的音频流如果是48000采样会导致转换失败，增加过滤处理。</span></p></li><li><p><span>修复应用最后的音量大小和静音状态时候在ffmpeg内核下有时候不成功的BUG。</span></p></li><li><p><span>实时检测摄像机是否在线，增加其他端口的识别，默认554端口，也可能有其他端口。</span></p></li><li><p><span>改进默认音量大小和静音状态设置逻辑，如果采用QAudioOutput播放音频则初始化的时候传入对应参数，如果是内核自带声音静音接口的则在打开成功以后主动去设置默认的音量大小和静音状态。</span></p></li><li><p><span>本地回放增加停止播放和静音切换图标按钮，并优化对应的处理逻辑。</span></p></li><li><p><span>修复qmedia内核静音切换对应标志位没有改变的BUG。</span></p></li><li><p><span>对视频监控控件新增获取是否暂停状态、音量大小、静音状态等函数。</span></p></li><li><p><span>本地回放新增当用户按下播放按钮右侧又选择了对应的文件则自动触发双击播放。</span></p></li><li><p><span>修复本地回放中停止播放后当还不是末尾一个视频文件时还会自动播放下一个的BUG，因为有自动播放机制，需要增加标志位判断，只要按下过停止按钮则无需自动播放。</span></p></li><li><p><span>修复ffmpeg内核在快速拖动进度条期间切换播放进度后小概率出现播放暂停的BUG。之前复用的暂停标志位，由于很多地方用到并且可能修改了暂停标志位导致恰时间点的不正确，新增了切换进度标志位，专用于切换进度判断，完美解决。</span></p></li><li><p><span>增加onvif指令过滤重复机制，当队列中有相同的onvif地址和指令的时候，不需要加入队列。</span></p></li><li><p><span>内核ffmpeg增加了实时码率的计算，统计的一个周期内（帧率25就统计25个包）所有视频数据包的总大小。</span></p></li><li><p><span>重新更新全部说明书，包括截图和文字说明。</span></p></li></ol><p><strong><span>V20221116</span></strong></p><ol start='' ><li><p><span>每个视频控件都可以手动开启和停止录像，开启的时候传入文件名即可。</span></p></li><li><p><span>修正视频控件边框大小计算当尺寸为奇数的时候不准确的情况，增加了偏移1个像素处理非常完美。</span></p></li><li><p><span>修复ffmpeg内核打开视频流中途分辨率变化后计算不正确的BUG，中途分辨率调整后策略改成重新打开。</span></p></li><li><p><span>修复ffmpeg内核在暂停阶段切换播放进度后会继续播放的BUG，应该是要继续处于暂停播放。</span></p></li><li><p><span>解码线程基类、保存线程基类都增加全局静态变量控制是否打印消息，由于解码线程等类中要打印的信息特别多，可以在需要的时候开启，几乎每一个重要的步骤或者可能出错的地方都会有对应打印信息，方便跟踪查找问题。有时候想关注其他地方的打印信息，为了避免给解码线程的打印信息冲掉，尤其是通道数量多的时候，信息类似涌过来，此时可以关闭解码线程的打印信息，专注于其他打印信息。</span></p></li><li><p><span>视频配置参数这块很多参数的设置改成了立即应用，比如边框大小、图片显示策略等，不能立即应用的也可以通过主界面中的停靠窗体设备控制单击刷新通道来应用。</span></p></li><li><p><span>录像计划改成了立即应用，添加、删除、修改后都会立即更新录像计划到视频管理线程类。</span></p></li><li><p><span>视频回放中的日期选择范围，改成了精确到分，无需精确到秒。</span></p></li><li><p><span>视频回放增加了倍速选项，可选0.5/1.0/2.0/4.0/8.0等倍速。设置完立即应用，下一个自动播放的也会立即应用该倍速。</span></p></li><li><p><span>视频管理线程类对切换保存文件的时间的精准度做了调整，比如30分钟一个文件，文件的时间是12:00:00到12:29:59，12:30:00到12:59:59，整半点开始，59秒结束。</span></p></li><li><p><span>目前的视频存储策略是中间存储的保证是30分钟的一个文件，头部和尾部，因为开启录像或者结束录像的时间未必是整半点，所以可能产生的录像文件的时间不一定的30分钟一个。</span></p></li><li><p><span>经过详细测试对比，如果是视频流，开启了变码流则视频大小未必一样，如果是定码流则几乎一样，变码流则文件大小相差比较大，视频中动静变化比较大或者颜色比较多的文件体积更大。</span></p></li><li><p><span>同样分辨率的视频流，用H265编码生成的视频文件体积比H264小很多（同一个摄像头同样主码流分辨率切换到H265存储体积大概是普通H264的40%，还有其他H264H/H264B之类的没有具体对比测试），本系统中的策略是源头是H264的就采用H264编码，源头是H265的就用H265编码存储。这样可以不用转码大大减轻CPU运算压力。</span></p></li><li><p><span>录像文件存储以本地时间为准，如果设备的时间和本地时间不一致，可能会看到摄像头视频文件上显示的时间和要求的时间不一致，在开启了onvif校时的情况下，大概会有3s左右的偏差，也就是说录像文件上显示的时间可能是走到10:30:03才结束，如果时间完全一致则应该是10:29:59。</span></p></li><li><p><span>增加目标秒数核对以便尽量保持录像时间以59秒结束，可以自行更改该目标秒数值保持一致。</span></p></li><li><p><span>所有下拉框中的通道字符串为了整齐统一改成了两位字符串比如 通道01、通道05、通道16，除了主界面通道文字是 通道1、通道5、通道16字样，其余全部两位。</span></p></li></ol><p><strong><span>V20221111</span></strong></p><ol start='' ><li><p><span>新增录像计划，增加录像任务计划控件，支持星期一到星期日每天24小时勾选是否录像，精确到30分钟间隔。</span></p></li><li><p><span>任务策略表格支持直接右键菜单全部选中、反向选中、清空选中操作。</span></p></li><li><p><span>新增录像计划表RecordInfo，对应字段RecordCh表示通道0-64，RecordWeek1-RecordWeek7表示星期一到星期日的录像计划字符串表示，通过占位符表示该30分钟时间内是否录像，每天有48个小格式。</span></p></li><li><p><span>通道唯一标识统一ch01到ch64字样，录像文件以及截图都按照这个作为文件的前缀，方便查找。</span></p></li><li><p><span>调整了一个设备多路通道（比如NVR或者部分相机）搜索的结果组合的策略，以便配置成多个不同的通道。大部分厂家的规则是每个通道一路主码流一路子码流，依次顺序存放。</span></p></li><li><p><span>录像计划新增批量一键添加64通道7 * 24小时录像，绝大部分时候都是这个情况所以可以一键添加，添加好以后有特殊的可以自行调整。</span></p></li><li><p><span>演示示例demo新增了配置参数保存对应选择的视频地址。</span></p></li><li><p><span>视频参数设置做了重大调整，按照新的解码内核来设计，更合理更贴切，把一些不需要的删除了。</span></p></li></ol><p><strong><span>V20220918</span></strong></p><p><strong><span>构思和编码及测试花了一年时间，将所有视频监控内核重新架构重写，抽象视频解码线程类和视频窗体展示类，着重解决了视频解码线程复用。具体可参见文档中的内核模块说明。</span></strong></p><p><strong><span>视频复用技术难点</span></strong></p><ul><li><p><span>通道1打开视频流A，通道2也打开视频流A，通道3也打开视频流A，此时通道1负责打开视频流A，其他两个通道公用通道1的视频流数据。</span></p></li><li><p><span>通道1关闭视频流A（仅仅是关闭映射，不能关闭视频流），通道2关闭视频流A（仅仅是关闭映射，不能关闭视频流），通道3关闭视频流A（关闭映射+关闭视频流）。</span></p></li><li><p><span>首次打开视频流地址的通道负责打开视频流。</span></p></li><li><p><span>末次关闭视频流地址的通道负责关闭视频流。</span></p></li></ul><p><strong><span>主要改进功能点</span></strong></p><ol start='' ><li><p><span>共享解码线程，相同地址的已经打开过的，直接复用，大大减轻网络流量和推流设备的压力。</span></p></li><li><p><span>动态内核挂载，解码和展示分离，通过基类的公共接口设计，视频控件可以任意动态挂载任意的解码内核，在打开的时候指定即可，内部会根据指定的内核自动实例化对应解码线程解码。</span></p></li><li><p><span>悬浮工具栏控件，各种颜色设置，包括透明度，位置可以上下左右，内容可以自定义。单击事件发信号，常用的录像、抓图、静音、关闭等按钮内置了实现，其余自定义按钮可以自行拿到信号做处理。空白处显示对应通道的分辨率、录像状态等信息，提供接口设置对应提示信息。</span></p></li><li><p><span>自定义标签OSD，任意多个，有多种类型和属性参数。</span></p></li><li><p><span>自定义图形，任意多个，直接绘制到原图上，有多种类型和属性参数。</span></p></li><li><p><span>视频控件基类，参数极其丰富，包括边框大小、边框颜色、焦点颜色、背景颜色、文字颜色、填充颜色、背景文字、背景图片、是否拷贝图片、缩放显示模式、视频显示模式等。</span></p></li><li><p><span>解码线程基类，参数极其丰富，包括解析内核、视频地址、缓存分辨率、解码策略、硬件加速、通信协议、缓存时间、循环播放、读取超时时间、连接超时时间等。</span></p></li><li><p><span>除了常规的视频文件、网络文件、视频流，还支持本地摄像头、旋转了90度的手机视频文件、非H264的文件自动转码显示。</span></p></li><li><p><span>对ffmpeg内核做了极度优化，支持音频视频文件保存，之前只支持rtsp视频流，而且生成的文件不标准没有文件属性分辨率信息等。</span></p></li><li><p><span>统一的打印格式，完整的信号通知，友好的接口设计。</span></p></li></ol><h4 id='082-破茧成蝶'><span>0.8.2 破茧成蝶</span></h4><p><strong><span>V20220625</span></strong></p><ol start='' ><li><p><span>在之前支持NVR所有通道批量添加基础上，增加自动添加NVR信息到表，这样每个NVR都会自动添加，如果有手动添加好的则取添加好的，以IP地址为准。</span></p></li><li><p><span>修复设备在线状态处理，在同一个NVR下IP地址相同的不同通道视频，不会处理在线状态的BUG。</span></p></li><li><p><span>修复在postgresql数据库和oracle数据库下，QSqlTableModel对应setTable设置表名严格区分大小写的BUG。</span></p></li><li><p><span>测试发现有些很老的设备支持的是onvif1.0，云台地址需要用getCapabilities才能拿到，改进这个处理，兼容任意版本。</span></p></li></ol><p><strong><span>V20220612</span></strong></p><ol start='' ><li><p><span>修复qss中分组框QGroupBox标题位移的BUG，在linux系统表现不统一。</span></p></li><li><p><span>改进同样的内容导出到pdf和打印显示效果不一致的情况，统一设置分辨率为96。</span></p></li><li><p><span>摄像机管理增加多选删除，删除的时候除了删除摄像机表中对应记录，也同时删除轮询信息表中的记录。</span></p></li><li><p><span>初始化数据库按钮增加弹框确认，由于这个操作安全级别非常高，增加弹框确认很有必要。</span></p></li><li><p><span>所有QTableView+QSqlTableModel对应的保存按钮代码增加主动设置焦点，避免mac系统中当单元格处于编辑状态，再去单击保存按钮，数据依然是之前的数据的BUG。</span></p></li><li><p><span>样式表全局颜色增加悬停背景颜色QUIConfig::HoverBgColor和选中背景颜色QUIConfig::SelectBgColor用于自定义委托。</span></p></li><li><p><span>对于加深的样式，重新设置单元格等item选中和悬停颜色 默认悬停-DarkColorEnd 选中-NormalColorEnd，加深颜色设置为相反。</span></p></li><li><p><span>增加全局参数控制是悬停颜色覆盖选中颜色还是选中颜色优先，默认选中颜色优先，这样选中的item鼠标移上去不会改变掉颜色。</span></p></li><li><p><span>增加过滤同名的NVR，之前会重复加载，现在限定同名的只加载一个，要求整个系统中NVR的名字必须唯一。</span></p></li><li><p><span>轮询管理中增加摄像机表的过滤条件，启用了的才显示在表格中。</span></p></li><li><p><span>增加播放记录开关，用于软件启动后，是否从播放记录url.txt读取历史记录进行播放。</span></p></li><li><p><span>增加播放记录url.txt过滤机制，只有摄像机表中存在且启用过的才可以播放。也可以改成只对rtsp开头的进行过滤。</span></p></li><li><p><span>增加选择列表通道的时候自动选中视频通道，高亮显示，这样很明确知道选择的哪个，同理，选中视频通道也高亮选中列表通道。相当于通道选中和列表选中联动。</span></p></li><li><p><span>增加设备列表在线离线不同图标显示，目前只对rtsp地址开头的进行实时监测上线离线状态，其他全部永远当做在线。离线图标颜色取系统设置中的报警图标颜色。</span></p></li><li><p><span>增加设备在线状态字段列表，实时监测设备状态期间先判断状态是否发生变化，只有发生变化了才需要去调用对应函数处理，大大减少无效的多余的处理。</span></p></li><li><p><span>修复设备列表双击空白处崩溃的BUG，需要过滤空节点item。</span></p></li><li><p><span>增加表格策略，单选按下编辑、多选双击编辑，有些用户需要多选摄像机列表删除。</span></p></li></ol><p><strong><span>V20220515</span></strong></p><ol start='' ><li><p><span>将用户退出中的退出系统权限验证去掉，理论上对退出系统这个限制没啥意义，还可以通过任务管理器强制关闭进程。</span></p></li><li><p><span>将退出系统的权限名称改成调整布局，没有调整布局权限则不能调整拖动停靠窗体位置等。</span></p></li><li><p><span>视频面板窗体对象指针放到了全局静态变量，这样很多地方可以直接使用，比如声音控制、布局调整、视频轮询等。这样就不用繁琐的信号槽切换，可以省略很多不必要的代码，性能更高。</span></p></li><li><p><span>修复静音状态下调整音量可能不正确的BUG，静音状态下只改变音量值变量而不是正常改变音量。</span></p></li><li><p><span>实现右下角音量面板静音切换、音量值调整，全局视频控件应用。</span></p></li><li><p><span>改进默认地图算法，取第一个有背景地图的设备的图片作为默认图片，可能默认图片不存在则取图片列表中的第一张。</span></p></li><li><p><span>修复ffmpeg内核回调模式自动重连崩溃的BUG，此时图片不存在应该置为空。</span></p></li><li><p><span>增加识别秘钥有限制后限定标题栏带试用字样。</span></p></li><li><p><span>重写通用的视频地址类videourl，将通道改成0开始，分隔符改成英文逗号，视频地址集合通过指定枚举值选择不同类型添加。</span></p></li><li><p><span>增加自动插入临时消息到数据库用户操作记录，增加参数控制是否需要显示临时消息的时候插入。</span></p></li></ol><p><strong><span>V20220413</span></strong></p><ol start='' ><li><p><span>修复视频控件设置自定义背景颜色的时候，没有考虑边框的范围问题。</span></p></li><li><p><span>选项卡样式去掉悬停样式，经过观察对比Qt自带的样式都是没有悬停样式，直接是选中样式。</span></p></li><li><p><span>修复自定义委托复选框不居中的问题，之前计算不准确会有细微偏差。</span></p></li><li><p><span>自定义委托增加悬停颜色。</span></p></li><li><p><span>重写自定义委托禁用列，支持文字颜色、背景颜色、字体等特性。</span></p></li><li><p><span>修复用户登录、用户退出界面标题栏字体被放大的BUG，因为样式冲突了。</span></p></li><li><p><span>将NvrInfo和IpcInfo中的地址字段改名为mark备注字段，涵盖内容更广。</span></p></li><li><p><span>地图模块默认卫星图增加了叠加层，更符合实际需求，对应地图综合应用示例做了极大升级改善，比如下载离线地图改成了最新的地址，可以下载到和在线地图一样的瓦片图片文件，离线地图下载改成了多线程，速度提升10倍以上。</span></p></li><li><p><span>自定义委托增加quistyle标记，有该标记则自动代码内部引用换肤全局颜色变量，这样删除了大量的设置自定义委托背景颜色的代码。</span></p></li><li><p><span>修复Qt6中msvc编译器下，强制指定miniblink浏览器内核的时候编译通不过的BUG，其实这个操作有点吃饱了撑着，因为msvc下有webengine浏览器内核。但是就是因为有极个别人有这个需求，客户就是上帝。</span></p></li><li><p><span>增加用户管理权限。</span></p></li><li><p><span>将用户权限和用户信息相关类合并到通用的类userhelper中，做成通用的权限组件。</span></p></li><li><p><span>修复Qt6中自定义复选框委托，在设置了全局样式的情况下，会不断切换选中的BUG。</span></p></li><li><p><span>效果图重新截图，用最新的运行界面。</span></p></li><li><p><span>组件示例增加4通道视频同时播放，进度条控制。</span></p></li></ol><p><strong><span>V20220106</span></strong></p><ol start='' ><li><p><span>彻底修复全屏模式+webengine同时存在的情况下鼠标右键菜单无法弹出以及视频可能黑屏的BUG，这是Qt的BUG。</span></p></li><li><p><span>同时测试多屏幕下正常状态和全屏状态的情况，多屏幕不同分辨率。</span></p></li><li><p><span>增加其他设置界面，将串口设置、网络设置等移动到其他设置。随着功能越来越多，也很有必要单独拆分设置。</span></p></li><li><p><span>修复打印预览看不到文字的BUG，原来是设置了QGraphicsView的前景色导致的，把前景色和背景色设置成一样的了，其实是有文字的，鬼想得到QPrintPreviewDialog里面的预览原来用的是QGraphicsView绘制的。</span></p></li><li><p><span>修复qchart图表控件鼠标按下松开后会跟随窗体移动的BUG，因为qchart鼠标按下是UngrabMouse事件而不是MouseButtonRelease。</span></p></li><li><p><span>修复表格行按下后自定义委托颜色在部分样式方案下设置不正确的BUG。</span></p></li><li><p><span>增加视频弹窗按钮，封装的统一的视频弹窗静态函数，直接传入url地址即可。</span></p></li><li><p><span>修复鼠标按下视频预览底部工具栏也能拖曳视频的BUG。</span></p></li><li><p><span>海康内核解析增加对通道的解析，比如可能是一个摄像机有多个通道，或者NVR多个通道。同时完善主码流子码流的解析，可以解析多个码流，之前只能解析主码流子码流两个。</span></p></li><li><p><span>海康内核句柄模式下增加等比例缩放自适应。</span></p></li><li><p><span>onvif模块修复部分厂家摄像机比如天地伟业，搜索返回的媒体地址等一系列请求地址，没有加onvif节点的BUG。</span></p></li></ol><p><strong><span>V20211220</span></strong></p><ol start='' ><li><p><span>重新梳理整个onvif模块，调整对应的结构，删除多余的变量和设置等，对应云台控制等操作需要指定profile，通过参数传入。</span></p></li><li><p><span>对应图片参数操作需要指定videosource，通过参数传入。</span></p></li><li><p><span>去除数据库字段mediaurl、ptzurl，因为这两个数据每次都是更新重新获取的，通过getServices获取，这两个字段改成了videosource、profiletoken，用来从数据库读取出来，每次使用的时候自动下发。</span></p></li><li><p><span>预置位表格中的按钮样式调整，去掉圆角，增加边距，效果更完美。</span></p></li><li><p><span>新增nvr多个通道onvif支持，改动onvif模块代码和数据库结构。</span></p></li></ol><ul><li><p><span>搜索设备后判断是否多个videosource，多个表示有多个视频源，一般是NVR，也有部分IPC自带多个视频源。</span></p></li><li><p><span>有多个则根据不同厂家不同规则，找出对应的每个通道的videosource、profiletoken、rtspmain、rtspsub用分隔符 | 插入到临时表格中。</span></p></li><li><p><span>摄像机管理界面接收到添加设备的时候，在addDevice槽函数中，判断发过来的数据，带了 | 要分别取出来作为通道添加到数据库中。</span></p></li></ul><ol start='6' ><li><p><span>重新定义搜索的摄像机设备命名规则，按照摄像机#ip地址末尾数字的方式。</span></p></li><li><p><span>如果是NVR过来的摄像机，增加自动查找NVR的名称插入数据库。</span></p></li><li><p><span>获取预置位增加立即清空所有行，之前是先清空内容再根据读取到的预置位个数设置行数。</span></p></li><li><p><span>增加双击打开NVR（也叫分组）对应策略 0-最后空白通道 1-从头清空通道。</span></p></li><li><p><span>增加双击打开IPC（也叫设备）对应策略 0-最后空白通道 1-最后按下通道。</span></p></li><li><p><span>改进在分辨率不同缩放比例保持一致的UI体验，不受缩放比例的影响。</span></p></li><li><p><span>修正异或加密，增加对@String开头的密文进行过滤，防止高版本产生的配置文件到低版本的Qt程序不能正确解析的BUG。</span></p></li><li><p><span>如果打开视频流出错提示 Server returned 5XX Server Error reply 表示摄像机的码流满了，可能多个地方在拉取码流导致摄像机输出的视频流被占满，已经没有更多资源。</span></p></li></ol><p><strong><span>V20211205</span></strong></p><ol start='' ><li><p><span>地图内核增加了海量点接口。</span></p></li><li><p><span>路径规划模块彻底重写，支持重新绘制、沿线移动等模式，数据表格显示。</span></p></li><li><p><span>设备轨迹模块改成从gps点集合文本文件加载进行循环动态模拟移动，默认飞机图标，以便转动角度。</span></p></li><li><p><span>设备播放增加保存视频开关配置参数，可以直接在界面上开启，开启后，通过rtsp从nvr取流比如回放视频，可以将回放的视频保存MP4文件到本地。</span></p></li><li><p><span>修正Qt6通过属性设置标签labtip不能居中对齐的BUG。</span></p></li><li><p><span>封装通用的设置一堆按钮比如添加、删除、保存、导入、导出等按钮图形字体的函数，直接传入父面板即可，自动查找对应的objname设置图标，省去一堆重复代码。</span></p></li><li><p><span>新增飞行轨迹模块frmDeviceGps2，之前的frmDeviceGps作为通过外部函数调用移动。</span></p></li><li><p><span>样式统一整理规范，分类6大类：black、dark、flat、light、normal、other。</span></p></li></ol><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><span><span>​</span>x</span></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">GlobalStyle::getStyle</span>(<span class="cm-variable">QStringList</span> <span class="cm-operator">&amp;</span><span class="cm-variable">styleNames</span>, <span class="cm-variable">QStringList</span> <span class="cm-operator">&amp;</span><span class="cm-variable">styleFiles</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">static</span> <span class="cm-variable">QStringList</span> <span class="cm-variable">names</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">names</span>.<span class="cm-variable">count</span>() <span class="cm-operator">==</span> <span class="cm-number">0</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"黑蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"软件黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"视频黑"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深黑色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深灰色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平蓝"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平灰"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅黑色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅灰色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通蓝"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通灰"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大紫色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大银色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//中文皮肤名称对应样式表文件</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">static</span> <span class="cm-variable">QStringList</span> <span class="cm-variable">files</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">files</span>.<span class="cm-variable">count</span>() <span class="cm-operator">==</span> <span class="cm-number">0</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blackblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blacksoft.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blackvideo.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/otherblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/otherpurple.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/othersilvery.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">styleNames</span> <span class="cm-operator">=</span> <span class="cm-variable">names</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">styleFiles</span> <span class="cm-operator">=</span> <span class="cm-variable">files</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 599px;"></div><div class="CodeMirror-gutters" style="height: 599px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><p><strong><span>V20211111</span></strong></p><ol start='' ><li><p><span>ONVIF组件增加图片参数范围获取，之前默认0-255，有些设备是0-100 0-128之类的，获取后设置到滑动条范围。</span></p></li><li><p><span>ONVIF组件增加网络参数设置，比如IP地址，子网掩码、网关地址、DNS设置等。</span></p></li><li><p><span>ONVIF组件将结构体定义统一移到一个头文件onvifstruct.h，方便后期拓展管理。</span></p></li><li><p><span>预置位模块，调用、添加（调用）、删除三种功能，改成了以三个按钮的形式加到每个预置位信息的后面直接单击使用。之前是先选中预置位所在行，然后单击下面的按钮。</span></p></li><li><p><span>通道轮询全部移动单独的悬停的模块。</span></p></li><li><p><span>视频面板窗体指针改成了全局变量，多处需要引用。</span></p></li><li><p><span>修复1通道轮询后，再次启动程序无法正确加载通道面板布局的BUG。</span></p></li><li><p><span>修复底部通道切换，部分样式效果悬停时候颜色不正确的BUG。改成了取报警图标颜色和已处理颜色。</span></p></li><li><p><span>路径规划模块增加模拟轨迹设备自动旋转角度移动。</span></p></li><li><p><span>路径规划模块模拟轨迹增加移动间隔下拉框选择。</span></p></li><li><p><span>修复Qt4对应webkit模块不支持返回数组的问题，改成字符串拼接用 ; 符隔开。</span></p></li><li><p><span>修复Qt4对应webkit模块不支持路径规划的BUG，因为开启了实时路况属性。</span></p></li><li><p><span>路径规划增加绘制实时轨迹线条，不同颜色显示。</span></p></li></ol><p><strong><span>V20211101</span></strong></p><ol start='' ><li><p><span>修正开启轮询后关闭所有视频通道不弹出提示信息。</span></p></li><li><p><span>所有信息框增加阴影边框区分突出显示，并跟随系统换肤自动更新边框阴影。</span></p></li><li><p><span>修正视频轮询分隔符，将|改成;因为如果是竖杠遇到带有参数的url则会出错。</span></p></li><li><p><span>将设备图片统一存放到config/device目录，之前在config目录下，随着越来越多非常凌乱。</span></p></li><li><p><span>修复之前通过信号执行通道切换，对应文字显示反了的BUG（通道1交换到通道2，新的通道2应该显示之前通道1的文本）。</span></p></li><li><p><span>将鼠标按下两个通道交换的处理代码，复用信号槽切换通道的函数。</span></p></li><li><p><span>将视频监控布局切换部分单独提取类VideoBox，专门负责管理各种通道布局切换，复用代码并且方便后期拓展，这部分代码和具体的处理无关，一直以来就想要单独提取出来进行管理，后期可以方便的增加其他异形布局以及255通道布局等，很多项目都用到了这个切换逻辑。</span></p></li><li><p><span>同时增加了布局切换子菜单比如13画面子菜单切换到52_64通道。</span></p></li><li><p><span>修复Qt6中视频控件悬浮条无法显示的BUG，因为Qt6将void enterEvent(QEvent *);改成了void enterEvent(QEnterEvent *);也不打个招呼。这种改变编译也不会提示的。</span></p></li><li><p><span>数据库组件修正sqlserver数据库必须设置数据源的不足，改成了dsn字符串形式，不需要新建数据源也能直接通信。</span></p></li><li><p><span>数据库组件修正mysql数据库必须存在默认数据库mysql的不足，改成了不需要默认数据库也能正常通信。</span></p></li><li><p><span>数据库组件修正没有默认数据库也能在建立连接后新建数据库操作。</span></p></li><li><p><span>数据库脚本执行将DROP DATABASE IF EXIST改成了DROP DATABASE ，这样无论什么时候都能先删除原来的数据库然后再新建数据库CREATE DATABASE。有些数据库不支持IF EXIST。</span></p></li></ol><p><strong><span>V20211005</span></strong></p><ol start='' ><li><p><span>修正ffmpeg内核，在播放地址不存在的情况下，打开容易卡主引起崩溃的BUG，在打开回调函数中增加对线程停止标志位的判断，一旦在打开的回调中识别到需要停止线程则立即返回结束。</span></p></li><li><p><span>增加临时信息中间弹出框提示信息，比如一次性关闭所有通道的时候，界面会卡主的期间提示。</span></p></li><li><p><span>增加忙碌鼠标图标切换显示，忙完以后自动恢复鼠标样式。</span></p></li><li><p><span>修正ffmpeg内核，开始时间记录可能出现问题的BUG，会导致部分特殊MP4文件打不开。</span></p></li><li><p><span>应用程序关闭，增加全局退出信号关联到视频通道管理类，先关闭所有视频通道再彻底退出应用程序。不这样处理的话，发现vlc内核在开启了视频存储的时候，会关不掉程序。</span></p></li><li><p><span>修复在没有声音播放的情况下主动调用停止播放造成崩溃的BUG。</span></p></li><li><p><span>修复在linux系统上QUIWidget弹出的无边框窗体带系统标题栏的BUG。</span></p></li><li><p><span>修复ffmpeg内核关闭视频后opengl窗体来不及隐藏的BUG。</span></p></li><li><p><span>修复重复立即刷新打开所有通道，前一次还没执行后一次又来了的BUG，改成了定时器处理，在立即执行前将上一次还没来得及执行的先停止。</span></p></li><li><p><span>增加about关于对话框窗体，显示版本号、版权所有、网址、电话等信息。</span></p></li><li><p><span>所有弹出窗体都跟随软件主窗体默认居中，这个特性非常棒。</span></p></li><li><p><span>所有皮肤增加右键菜单选中图标样式、右键菜单二级子菜单右侧小三角箭头图标样式，单选框、复选框、禁用状态图标全部更新，从图形字体绘制，极其统一舒服。</span></p></li><li><p><span>着重对日志类savelog增加了最大行数、最大文件大小等参数设置，可以设置按照行数或者大小来自动分割日志文件。</span></p></li><li><p><span>日志类增加了可过滤不同的消息类型，不同消息类型增加消息头。</span></p></li><li><p><span>经过大量对比测试发现，使用miniblink浏览器内核，容易卡，说不定什么时候就失效了，问题集中在32位，64位的目前没有发现这个现象，webengine暂时没有这个现象，但是加载打开摄像机的网页配置，还是miniblink更优秀。</span></p></li><li><p><span>中文标题栏支持换行，既可以副标题写在英文标题上，也可以同等大小字体写在中文标题上。</span></p></li></ol><p><strong><span>V20210922</span></strong></p><ol start='' ><li><p><span>视频控件边框增加0像素选项，这样看起来没有边框，有些场景需要无缝拼接。</span></p></li><li><p><span>修复当采用NVR通道作为摄像机视频流显示的时候，ONVIF处理索引越界崩溃的情况，因为一台NVR同一个IP地址对应多个摄像机。</span></p></li><li><p><span>所有样式17套皮肤更新边框颜色。</span></p></li><li><p><span>系统信息增加对应的编译器名字、位数、版本等。</span></p></li><li><p><span>演示demo增加视频叠加演示功能，比如在主视频的左上角、右上角、左下角、右下角在增加一个视频缩略图显示。</span></p></li><li><p><span>新增天气预报模块，可设置城市、采集间隔、展示样式等。</span></p></li><li><p><span>增加了vlc内核下本地摄像头格式自动纠正，如果采用ffmpeg的格式video=USB2.0 PC CAMERA|1920x1080自动纠正。</span></p></li><li><p><span>纠正vlc内核下本地摄像头不自动拉伸的BUG。</span></p></li><li><p><span>修正vlc内核动态保存视频文件，文件命名不符合规范，重新按照设定的重命名。</span></p></li><li><p><span>修复vlc内核中本地摄像头会当做rtsp视频流的BUG。</span></p></li><li><p><span>天气预报模块新增城市显示，新增双击弹出天气预报设置，含打印信息。</span></p></li><li><p><span>系统信息，增加秘钥文件的内容，比如允许的设备数量、到期日期等。</span></p></li><li><p><span>修复配置文件一旦新增加节点，之前节点全部初始值运行的BUG，应该是存在的节点则读取节点值，不存在的节点以初始值运行。</span></p></li></ol><p><strong><span>V20210705</span></strong></p><ol start='' ><li><p><span>改进窗体居中显示算法，可设置参照窗体，默认基于当前屏幕中心，可设置参照主窗体则基于参照窗体，在大分辨率屏幕效果非常好，不然主窗体很小，弹个窗找不到还在很远的地方，还以为没有弹呢。</span></p></li><li><p><span>将登陆窗体、登出窗体、用户管理等公用界面，做成了通用库core_form。</span></p></li><li><p><span>修复MAC系统上无边框窗体无法最小化的BUG。</span></p></li><li><p><span>增加超级管理员密码A具有所有权限的机制，避免管理员误将系统设置权限取消后无法再次进去系统设置的问题。</span></p></li><li><p><span>图片参数增加锐度，图片参数设置滑块调节松开立即设置。</span></p></li><li><p><span>修复当没有启用图片地图的时候对应界面隐藏的时候保存设备坐标位置报错BUG，因为没有启用的情况下没有设置对应的对象指针。</span></p></li></ol><p><strong><span>V20210603</span></strong></p><ol start='' ><li><p><span>将onvif搜索的用户密码，设备播放界面的设备密码等配置参数全部改成了密文存储。</span></p></li><li><p><span>大量修改代码，全部支持Qt4-Qt6所有版本。</span></p></li><li><p><span>调整onvif代码执行机制，改成了异步执行。</span></p></li><li><p><span>云台协议增加了连续移动。</span></p></li><li><p><span>增加了预置位相关处理，包括获取预置位、调用预置位、添加预置位、删除预置位。</span></p></li><li><p><span>自动巡航按照预置位集合进行，采用定时器去调用预置位队列。</span></p></li><li><p><span>增加图文警情行数、窗口信息行数配置，0行表示自动处理。</span></p></li><li><p><span>做了大量的代码改进，比如onvif内核换成了QDom对象处理，之前是采用的QXmlQuery查询，由于XmlPatterns这个模块逐渐废弃了，而且在Qt6中不再有，所以彻底移除了XmlPatterns相关的代码，改用其他处理方式实现。</span></p></li><li><p><span>增加了预置位和自动巡航处理，其中包括获取预置位集合、调用预置位、添加预置位、删除预置位、设置起始位、调用起始位等。</span></p></li><li><p><span>ONVIF内核几乎全部重写，将数据改成了结构体，比如设备信息、预置位信息、事件信息等，可以存储更多的数据，拓展也非常灵活。</span></p></li><li><p><span>onvif处理部分增加了对非onvif设备的过滤，通过判断是否存在onvif地址。这样可以大大加快处理速度，打开视频的时候去实例化onvif通信，关闭视频的时候删除对应的onvif类，这样可以动态响应。</span></p></li><li><p><span>所有onvif指令改成了线程处理，处理完成一个立马处理下一个，排队处理。</span></p></li></ol><p><strong><span>V20210425</span></strong></p><ol start='' ><li><p><span>配置文件密码改成密文存储。</span></p></li><li><p><span>增加了无敌的牛逼的万能的完美入微级自动分页导航控件。</span></p></li><li><p><span>日志记录表增加索引，速度提升100倍以上。</span></p></li><li><p><span>新增多个设备轨迹 不同颜色+传入经纬度 单独示例。</span></p></li><li><p><span>对地图核心类所有覆盖物都增加颜色+粗细+透明度的参数，可动态传入对应值。</span></p></li><li><p><span>系统设置增加用户管理模块，可分别设置对应的权限。</span></p></li><li><p><span>万能权限管理算法，通过设置不同需要授权的模块名称，对应切换的按钮自动计算。</span></p></li><li><p><span>增加了appkey秘钥类，用于校验秘钥是否正确，运行时间等。</span></p></li></ol><p><strong><span>V20210403</span></strong></p><ol start='' ><li><p><span>增加全局变量AppData::LastLiveTime，记住程序最后的活动时间-包括键盘+鼠标活动，用于两个判断，一个是超过多久没有操作全屏下隐藏鼠标光标，一个是超过多久没有操作如果没有全屏则自动全屏。</span></p></li><li><p><span>增加App::TimeAutoFull配置参数用来判断比较超时自动全屏。</span></p></li><li><p><span>重命名为TimeHideCursor表示程序多久未操作自动隐藏光标，TimeAutoFull程序多久未操作自动全屏界面，下拉框选项值增加0，表示不启用此功能。</span></p></li><li><p><span>增加信息列表模块frmMsgList，用于图文列表显示信息，对应兄弟类frmMsgTable用于表格显示消息。</span></p></li><li><p><span>大改版，将中间部分全部改成了QMainWindow，子模块全部采用停靠窗体，可以悬浮半透明，自动记忆每个模块的最后的位置，启动后自动应用。</span></p></li><li><p><span>移除大改版后的所有不需要用的变量和配置参数，重新调整配置参数。</span></p></li><li><p><span>增加透明度参数用于停靠窗体独立出来后的透明度。</span></p></li><li><p><span>将摄像机控制部分比如云台+控制+预置位+巡航，单独分类到ipc模块，方便管理。</span></p></li><li><p><span>限定操作员不能移动停靠窗体等，需要管理员设计好。</span></p></li><li><p><span>修复系统设置中工作模式等切换造成的自动重启会弹出退出和登录两个窗体的BUG。</span></p></li><li><p><span>修复自动登录用户计算不正确的BUG，要以最后登录的用户为准。</span></p></li></ol><p><strong><span>V20210322</span></strong></p><ol start='' ><li><p><span>本地摄像头增加参数帧率，第二个参数是分辨率，第三个参数为帧率，不设置则采用默认的帧率，video=USB2.0 PC CAMERA|1920x1080|25。</span></p></li><li><p><span>增加独立的demo模块，专门用于测试监控系统中用到的组件和控件，演示如何使用，比如视频图片界面演示从文件夹读取图片绘制到窗体，视频窗体演示系统的核心组件视频控件的设置参数如何使用等。</span></p></li><li><p><span>增加了对其他数据库的支持，比如posgres、oracle、odbc、kingbase等数据库，理论上只要支持odbc数据源方式的都支持。</span></p></li><li><p><span>增加IndexStart启动窗体索引配置参数，0-主程序 1-演示示例。</span></p></li></ol><p><strong><span>V20210305</span></strong></p><ol start='' ><li><p><span>修复数据库有时候没加载到的BUG。</span></p></li><li><p><span>新增配置参数控制画面切换的菜单和快捷图标是否显示。</span></p></li><li><p><span>ffmpeg内核增加了可动态保存机制，点击开始保存按钮启动保存，单击结束则生成视频文件，如此往复。</span></p></li><li><p><span>海康内核判断主码流子码流改成了 /101? 和 /main/ 同时判断。</span></p></li><li><p><span>新增多屏幕的支持，自动在对应屏幕最大化全屏，对话框位置，右下角提示框等。</span></p></li><li><p><span>再次分类存放代码文件，分成core ui class三大类。</span></p></li><li><p><span>系统配置更改视频控件参数，统一一个函数设置，initCommonVideoWidget函数中做了过滤，必须关闭状态的视频控件设置才起作用。</span></p></li><li><p><span>设备播放模块增加大华NVR的远程回放地址，其他地址计算算法调整。</span></p></li><li><p><span>新增界面模块功能启用配置参数。</span></p></li><li><p><span>新增主界面顶部导航模块中间界面，用于不同的运行模式加载不同的模块。</span></p></li></ol><h4 id='083-快速迭代'><span>0.8.3 快速迭代</span></h4><p><strong><span>V20201212</span></strong></p><ol start='' ><li><p><span>增加USB摄像机分辨率设置，直接url带掉。</span></p></li><li><p><span>所有地图内核公用一个，复用代码。</span></p></li><li><p><span>增加地图默认级别和中心点坐标设置参数。</span></p></li><li><p><span>主界面四个模块独立出来，做成了可配置，这样后期可以任意位置放置自定义模块。</span></p></li><li><p><span>四个模块标题栏自定义。</span></p></li><li><p><span>vlc内核和mpv内核的离线判断，当句柄模式下，统一为getLastTime，当调用该函数的时候自动查询播放状态，如果正在播放则自动更新时间为当前时间。</span></p></li><li><p><span>将各种在代码中define定义不同内核的代码全部优化，统一为一个类，很大减少代码量，统一为CommonVideoWidget和CommonVideoManage类。</span></p></li></ol><p><strong><span>V20201108</span></strong></p><ol start='' ><li><p><span>轮询点模块增加批量生成功能。</span></p></li><li><p><span>录像机、摄像机、轮询点，增加导入导出功能。</span></p></li><li><p><span>ffmpeg内核增加读取帧回调，超时识别，可以快速识别掉线。</span></p></li></ol><p><strong><span>20200828</span></strong></p><ol start='' ><li><p><span>增加了云台控制过滤，没有打开的视频禁用云台。</span></p></li><li><p><span>linux上全屏BUG修复，采用showfullscreen。</span></p></li><li><p><span>增加轮询点管理模块。</span></p></li><li><p><span>修正轮询的可能崩溃的BUG。</span></p></li></ol><p><strong><span>V20200730</span></strong></p><ol start='' ><li><p><span>系统设置增加了视频上传模块，用来将本地的视频文件传输到服务器，多线程并发。</span></p></li><li><p><span>视频监控内核新增MPV内核，修正了其他内核的部分函数和处理。</span></p></li><li><p><span>海康内核进行大改动，同时支持视频流和本地MP4文件播放，自动分析切换。</span></p></li><li><p><span>海康内核增加回调处理，可以拿到每一张图片。</span></p></li><li><p><span>海康内核进行了linux上的实验，可以正常播放。</span></p></li><li><p><span>ffmpeg内核增加保存到MP4。</span></p></li><li><p><span>本地文件回放vlc部分增加进度切换等。</span></p></li><li><p><span>悬浮条关闭按钮增加实际处理，之前只是打印消息。</span></p></li><li><p><span>改进了vlc和mpv的事件回调机制，使其同时支持qt4+qt5。</span></p></li></ol><p><strong><span>V20200620</span></strong></p><ol start='' ><li><p><span>增加了opengl显示实时视频，CPU占用极低。</span></p></li><li><p><span>增加了地图上设备点位置的调整。</span></p></li><li><p><span>设备点双击弹出实时视频预览。</span></p></li><li><p><span>增加GPS运动轨迹显示。</span></p></li><li><p><span>ffmpeg解码类增加了音频播放，采用的QAudioOutput。</span></p></li></ol><p><strong><span>V20191105</span></strong></p><ol start='' ><li><p><span>增加云台控制功能，可以上下左右等八个方位控制云台，默认采用相对移动，云台中间按下表示复位。</span></p></li><li><p><span>系统设置增加码流类型选择，默认子码流，切换完自动应用。</span></p></li><li><p><span>云台控制增加速度功能，值越大，速度越快。</span></p></li><li><p><span>增加焦距控制，可放大缩小，速度也可控制。</span></p></li></ol><h2 id='1-用户登录退出'><span>1 用户登录退出</span></h2><h3 id='11-用户登录'><span>1.1 用户登录</span></h3><p><span> </span><img src="snap/1-1-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/1-1-2.jpg" referrerpolicy="no-referrer"></p><p><span>系统启动后，首先会弹出用户登录界面，从用户姓名的下拉框选择用户名，然后输入密码（默认用户名密码都是admin），单击登录按钮，密码正确则会进入到系统主界面，错误会弹出提示，错误超过三次自动关闭，需要重新打开软件。</span></p><p><span>在登录界面可以勾选是否记住密码，是否自动登录，如果勾选了记住密码，则下次启用软件会自动填入最后用户的密码，勾选了自动登录（以最后的用户信息作为当前登录用户）则启动后直接进入主界面。如果开启了自动登录，不会弹出登录界面，可以在系统设置中关闭自动登录和记住密码。</span></p><h3 id='12-用户退出'><span>1.2 用户退出</span></h3><p><span> </span><img src="snap/1-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>在主界面单击右上角的关闭按钮，会弹出用户退出界面，需要输入密码验证防止误关闭，会自动填入登录的用户名，密码输入正确才会退出软件。用户登录和退出都内置了超级密码a防止管理员忘记密码。</span></p><h2 id='2-主界面操作'><span>2 主界面操作</span></h2><p><span> </span><img src="snap/2-0-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-0-2.jpg" referrerpolicy="no-referrer"></p><p><span>主界面由顶部主菜单导航、左侧右侧停靠窗体（设备列表、窗口信息、图文警情、悬浮地图、云台控制、设备控制、预置巡航、视频轮询等）、中间视频监控主画面组成，其中左右两侧的停靠窗体可以拉伸宽度，上下停靠窗体之间也可以拉伸高度，每个停靠窗体都可以关闭和悬浮。自动保存布局文件，下次启动自动应用。</span></p><p><strong><span>新增说明</span></strong></p><ul><li><p><span>2021-5-8，主界面改成了停靠窗体模式。</span></p></li><li><p><span>拓展性更强，可以任意组合多种子模块。</span></p></li><li><p><span>模块可停靠悬浮。</span></p></li><li><p><span>在普通模式和全屏模式都有独立的布局文件。</span></p></li><li><p><span>不同的工作模式都可对应不同的布局文件。</span></p></li></ul><h3 id='21-模块显示'><span>2.1 模块显示</span></h3><p><span> </span><img src="snap/2-1-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-1-2.jpg" referrerpolicy="no-referrer"></p><p><span>左侧和右侧的面板，可以通过单击面板右上角的关闭按钮来隐藏，当隐藏一个面板以后，剩余的面板会自动填充布局，如果需要重新显示面板，则在标题栏鼠标右键就可以对小面板进行显示和隐藏，右上角的时间和CPU显示面板可以在系统设置中控制显示隐藏。系统会自动记住最后的布局比如显示的面板和宽高占比，下次启动后自动应用。</span></p><p><strong><span>特别说明</span></strong></p><ol start='' ><li><p><span>在停靠窗体的标题栏鼠标右键也会弹出子窗体的开启菜单，复选框勾选表示显示，悬浮的窗体没有这个特性，一定要是嵌入在主界面中的子窗体标题栏才有。</span></p></li><li><p><span>如果是全屏模式，由于没有了标题栏，想要关闭模块的话，需要将其拖动到边缘嵌入主窗体，然后在标题栏鼠标右键菜单中关闭即可。</span></p></li></ol><h3 id='22-模块拖动'><span>2.2 模块拖动</span></h3><p><span> </span><img src="snap/2-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>面板和面板之间有个分隔条，鼠标移到对应分隔条的地方，会变成可拉动的鼠标指针，此时可以上下左右拉动调整宽高，调整好以后会自动保存宽高比例，下次启动后自动应用最后的配置来显示。</span></p><h3 id='23-视频播放'><span>2.3 视频播放</span></h3><p><span> </span><img src="snap/2-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>视频播放支持多种方式：</span></p><ol start='' ><li><p><span>双击子节点播放单个摄像机，在当前选中通道处播放。</span></p></li><li><p><span>双击父节点播放整个录像机的摄像机，依次排列。</span></p></li><li><p><span>按住子节点拖曳到对应通道，播放摄像机。</span></p></li><li><p><span>本地文件直接拖曳到通道，自动播放本地文件。</span></p></li><li><p><span>启动后自动播放最后通道的视频信息。</span></p></li><li><p><span>代码接口提供指定通道播放url。</span></p></li><li><p><span>代码接口提供指定两个通道交换，比如报警的时候将某个通道移到最前面显示。</span></p></li></ol><h3 id='24-视频截图'><span>2.4 视频截图</span></h3><p><span> </span><img src="snap/2-4-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-4-2.jpg" referrerpolicy="no-referrer"></p><p><span>视频截图支持多种方式：</span></p><ol start='' ><li><p><span>监控通道鼠标右键，弹出菜单选择截图当前视频/截图所有视频。</span></p></li><li><p><span>视频面板底部工具栏截图按钮。</span></p></li><li><p><span>每个通道悬浮工具条截图按钮。</span></p></li><li><p><span>截图默认保存在可执行文件所在目录下的image_normal目录，文件名格式ch01_2022-11-24-13-41-24-000.jpg。</span></p></li><li><p><span>底部工具栏截图按钮触发截图后会弹出提示抓拍文件后的保存位置。</span></p></li></ol><h3 id='25-删除视频'><span>2.5 删除视频</span></h3><p><span> </span><img src="snap/2-5-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-5-2.jpg" referrerpolicy="no-referrer"></p><p><span>有多种方法可以删除视频：</span></p><ol start='' ><li><p><span>鼠标右键删除当前视频。</span></p></li><li><p><span>鼠标右键删除所有视频。</span></p></li><li><p><span>按住通道画面移出视频监控画面。</span></p></li><li><p><span>悬浮条关闭按钮。</span></p></li></ol><h3 id='26-画面切换'><span>2.6 画面切换</span></h3><p><span> </span><img src="snap/2-6-1.jpg" referrerpolicy="no-referrer"></p><p><span>系统支持多画面切换，全屏切换等，包括1+4+6+8+9+13+16+25+36+64画面切换，如果还需要增加更多的画面比如81+100等，可以直接在源码中稍微修改即可。</span></p><ol start='' ><li><p><span>鼠标右键画面切换。</span></p></li><li><p><span>底部左侧画面切换缩略图。</span></p></li><li><p><span>快捷键alt+enter全屏。</span></p></li><li><p><span>快捷键esc退出全屏。</span></p></li></ol><p><span>64画面效果图</span>
<span> </span><img src="snap/2-6-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-6-3.jpg" referrerpolicy="no-referrer"></p><h3 id='27-声音调节'><span>2.7 声音调节</span></h3><p><span> </span><img src="snap/2-7-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-7-2.jpg" referrerpolicy="no-referrer"></p><p><span>在主界面画面栏右下角，按下声音图标自动弹出声音调节面板，失去焦点自动隐藏，拉动声音滚动条来调节声音大小，还有静音切换。右下角的声音和静音切换是针对所有通道的，单个通道可以在每个通道的悬浮条工具栏中单击静音切换按钮。</span></p><h3 id='28-视频轮询'><span>2.8 视频轮询</span></h3><p><span> </span><img src="snap/2-8-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>功能说明</span></strong></p><ol start='' ><li><p><span>开启是否一运行自动轮询。</span></p></li><li><p><span>可设置轮询间隔，比如5s、10s、30s、60s等。</span></p></li><li><p><span>可设置轮询画面类型，比如1画面、4画面、9画面、16画面。</span></p></li><li><p><span>可选择切换不同的轮询方案。</span></p></li><li><p><span>开始轮询和停止轮询。</span></p></li><li><p><span>暂停轮询和继续轮询。</span></p></li></ol><h3 id='29-通道交换'><span>2.9 通道交换</span></h3><p><span> </span><img src="snap/2-9-1.jpg" referrerpolicy="no-referrer"></p><p><span>通道交换功能很常用，一般用户喜欢调整自己想要的通道显示到前面或者占据画面的更大部分，比如6画面8画面的时候，左侧有一个画面占据很大的位置，一般这个用来显示重要性最高的实时视频，如果需要通道交换，则按住通道拖动到另外一个通道上面松开鼠标即可，会立即应用，瞬间切换，这里切记不要移出视频画面外，移出去表示删除。</span></p><p><span>本系统也封装了代码中动态控制切换和动态交换，具体代码在DeviceThreadUI类中，具体全局函数在AppEvent类中。</span></p><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 36px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 28px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>5</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -28px; width: 28px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//指定通道显示视频 id从0开始</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">slot_loadVideo</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">channel</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">ipcID</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">slot_loadVideo</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">channel</span>, <span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">url</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//通道交换</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">slot_changeVideo</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">channel1</span>, <span class="cm-variable-3">int</span> <span class="cm-variable">channel2</span>);</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 115px;"></div><div class="CodeMirror-gutters" style="height: 115px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 27px;"></div></div></div></div></pre><h3 id='210-云台控制'><span>2.10 云台控制</span></h3><p><span> </span><img src="snap/2-10-1.jpg" referrerpolicy="no-referrer"></p><p><span>如果需要控制云台移动，先要选择对应的通道，边缘会高亮，进行云台控制的前提是该摄像机要是支持云台的摄像机，很多人以为啥摄像机都可以移动，这是错误的，如果摄像机不支持云台，这个功能就别玩了，玩不起，经常遇到一些人说怎么云台不能用了，一检查尼玛原来摄像机根本没有云台。</span></p><p><span>本系统云台控制走的是onvif协议，没有使用私有协议，上百家厂家的摄像机，走私有协议会玩死人的，所以统一采用onvif通用协议，需要提前在系统设置中的摄像机管理，搜索摄像机，输入正确的onvif用户信息后一键获取到云台地址。具体操作参见  </span><a href='#638-设备搜索'><span>设备搜索</span></a></p><h3 id='211-设备控制'><span>2.11 设备控制</span></h3><p><span> </span><img src="snap/2-11-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备控制部分，目前可以获取和设置图片参数、手动校时、重启设备等，上面那一堆复选框对应功能需要用厂家sdk去实现，后期可能会增加一些onvif能够处理的功能。和云台控制操作一样，操作前也是需要选中某个通道，然后才是对选中的通道进行设备控制，比如图片参数中的明亮度、对比度、饱和度。</span></p><h3 id='212-报警订阅'><span>2.12 报警订阅</span></h3><p><span> </span><img src="snap/2-12-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/2-12-2.jpg" referrerpolicy="no-referrer"></p><p><span>本系统默认支持海康、大华、宇视、华为、天地伟业等厂家的摄像机的报警事件订阅，可以在系统设置中的视频参数设置中开启事件订阅开关，如果摄像机已经开启了报警事件的话（一般摄像机的网页配置界面进去有移动侦测、遮挡报警、人脸识别、报警输入等各种），默认一般是关闭的，比如摄像机后面的开关量输入报警接口，需要web页面进去设置开启。</span></p><p><span>报警订阅走的是onvif协议，具体事件内容和含义可以在config/event.txt事件字典表中修改，由于onvif事件有多种，而且不同厂家对应关键字对应的事件含义可能不一样，不同厂家的设备可能含义有点出入，所有可以通过事件字典表自行更改，对应内容含义 事件等级/唯一标识/报警字样/解除字样，默认程序按照这个表中的进行过滤，不在表中的可以正常收到但是不会处理。</span></p><p><span>常用几种事件字典：</span></p><ul><li><p><span>1,IsMotion,有人在移动,移动结束</span></p></li><li><p><span>1,IsInside,有人在闯入,入侵结束</span></p></li><li><p><span>1,LogicalState,开关量报警,报警结束</span></p></li><li><p><span>1,State,开关量联动,联动结束</span></p></li></ul><h3 id='213-悬浮工具'><span>2.13 悬浮工具</span></h3><p><span> </span><img src="snap/2-13-1.jpg" referrerpolicy="no-referrer"></p><p><span>悬浮条功能介绍：</span></p><ol start='' ><li><p><span>内置悬浮条控件，悬浮条位置支持顶部、底部、左侧、右侧。</span></p></li><li><p><span>悬浮条控件参数包括边距、间距、背景透明度、背景颜色、文本颜色、按下颜色、位置、按钮图标代码集合、按钮名称标识集合、按钮提示信息集合。</span></p></li><li><p><span>悬浮条控件一排工具按钮可自定义，通过结构体参数设置，图标可选图形字体还是自定义图片。</span></p></li><li><p><span>悬浮条按钮内部实现了录像切换、抓拍截图、静音切换、关闭视频等功能，也可以自行在源码中增加自己对应的功能。</span></p></li><li><p><span>悬浮条按钮对应实现了功能的按钮，有对应图标切换处理，比如录像按钮按下后会切换到正在录像中的图标，声音按钮切换后变成静音图标，再次切换还原。</span></p></li><li><p><span>悬浮条按钮单击后都用名称唯一标识作为信号发出，可以自行关联响应处理。</span></p></li><li><p><span>悬浮条空白区域可以显示提示信息，默认显示当前视频分辨率大小，可以增加帧率、码流大小等信息。</span></p></li></ol><h3 id='214-标签叠加'><span>2.14 标签叠加</span></h3><p><span> </span><img src="snap/2-14-1.jpg" referrerpolicy="no-referrer"></p><p><span>可动态添加任意多个osd标签信息，标签信息包括名字、是否可见、字号大小、文本文字、文本颜色、标签图片、标签坐标、标签格式（文本、日期、时间、日期时间、图片）、标签位置（左上角、左下角、右上角、右下角、居中、自定义坐标）。</span></p><p><span>具体结构体参数和使用方法如下：</span></p><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>65</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//标签信息</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">struct</span> <span class="cm-def">OsdInfo</span> {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QString</span> <span class="cm-variable">name</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//名字唯一标识符(方便删除或更新)</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">bool</span> <span class="cm-variable">visible</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//是否可见</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">int</span> <span class="cm-variable">fontSize</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//字号大小</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QString</span> <span class="cm-variable">text</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//文本文字</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QColor</span> <span class="cm-variable">color</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//文本颜色</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QImage</span> <span class="cm-variable">image</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//标签图片</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QPoint</span> <span class="cm-variable">point</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//标签坐标(位置自定义时候使用)</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">OsdFormat</span> <span class="cm-variable">format</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//标签格式</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">OsdPosition</span> <span class="cm-variable">position</span>; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//标签位置</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">OsdInfo</span>() {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">name</span> <span class="cm-operator">=</span> <span class="cm-string">"osd"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">visible</span> <span class="cm-operator">=</span> <span class="cm-atom">true</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">fontSize</span> <span class="cm-operator">=</span> <span class="cm-number">12</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">text</span> <span class="cm-operator">=</span> <span class="cm-string">"视频标签"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">color</span> <span class="cm-operator">=</span> <span class="cm-string">"#FF0000"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">image</span> <span class="cm-operator">=</span> <span class="cm-variable">QImage</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">point</span> <span class="cm-operator">=</span> <span class="cm-variable">QPoint</span>(<span class="cm-number">0</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">format</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdFormat_Text</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">position</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdPosition_LeftTop</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">};</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">27</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">28</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">public</span> <span class="cm-variable">slots</span>:</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">29</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//设置OSD标签</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">30</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">setOsd</span>(<span class="cm-keyword">const</span> <span class="cm-variable">OsdInfo</span> <span class="cm-operator">&amp;</span><span class="cm-variable">osd</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">31</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//添加OSD标签</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">32</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">appendOsd</span>(<span class="cm-keyword">const</span> <span class="cm-variable">OsdInfo</span> <span class="cm-operator">&amp;</span><span class="cm-variable">osd</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">33</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//移除OSD标签</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">34</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">removeOsd</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">name</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">35</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//清空OSD标签</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">36</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">clearOsd</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">37</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">38</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">DeviceVideoSmart::receiveData</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">type</span>, <span class="cm-keyword">const</span> <span class="cm-variable">QVariant</span> <span class="cm-operator">&amp;</span><span class="cm-variable">data</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">39</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">40</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-operator">!</span><span class="cm-variable">widget</span> <span class="cm-operator">||</span> <span class="cm-operator">!</span><span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">getIsRunning</span>()) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">41</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">return</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">42</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">43</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">44</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-string">"currentCount"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">45</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable-3">int</span> <span class="cm-variable">currentCount</span> <span class="cm-operator">=</span> <span class="cm-variable">data</span>.<span class="cm-variable">toInt</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">46</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">OsdInfo</span> <span class="cm-variable">osd</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">47</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">name</span> <span class="cm-operator">=</span> <span class="cm-string">"currentCount"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">48</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">fontSize</span> <span class="cm-operator">=</span> <span class="cm-number">20</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">49</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">text</span> <span class="cm-operator">=</span> <span class="cm-variable">QString</span>(<span class="cm-string">"当前人数: %1"</span>).<span class="cm-variable">arg</span>(<span class="cm-variable">currentCount</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">50</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">color</span> <span class="cm-operator">=</span> <span class="cm-string">"#D64D54"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">51</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">format</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdFormat_Text</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">52</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">position</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdPosition_LeftBottom</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">53</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">setOsd</span>(<span class="cm-variable">osd</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">54</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-string">"maxCount"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">55</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable-3">int</span> <span class="cm-variable">maxCount</span> <span class="cm-operator">=</span> <span class="cm-variable">data</span>.<span class="cm-variable">toInt</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">56</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">OsdInfo</span> <span class="cm-variable">osd</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">57</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">name</span> <span class="cm-operator">=</span> <span class="cm-string">"maxCount"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">58</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">fontSize</span> <span class="cm-operator">=</span> <span class="cm-number">20</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">59</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">text</span> <span class="cm-operator">=</span> <span class="cm-variable">QString</span>(<span class="cm-string">"限定人数: %1"</span>).<span class="cm-variable">arg</span>(<span class="cm-variable">maxCount</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">60</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">color</span> <span class="cm-operator">=</span> <span class="cm-string">"#FDCD72"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">61</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">format</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdFormat_Text</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">62</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">osd</span>.<span class="cm-variable">position</span> <span class="cm-operator">=</span> <span class="cm-variable">OsdPosition_RightBottom</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">63</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">setOsd</span>(<span class="cm-variable">osd</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">64</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">65</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 1497px;"></div><div class="CodeMirror-gutters" style="height: 1497px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><h3 id='215-图形绘制'><span>2.15 图形绘制</span></h3><p><span> </span><img src="snap/2-15-1.jpg" referrerpolicy="no-referrer"></p><p><span>可动态添加任意多个图形信息，这个非常有用，比如人工智能算法解析后的图形区域信息直接发给视频控件即可。图形信息支持任意形状，直接绘制在原始图片上，采用绝对坐标。</span></p><p><span>具体结构体参数和使用方法如下：</span></p><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>44</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//图形信息(人脸框和多边形区域等)</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">struct</span> <span class="cm-def">GraphInfo</span> {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QString</span> <span class="cm-variable">name</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//名字唯一标识符(方便删除或更新)</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">int</span> <span class="cm-variable">borderWidth</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">//边框大小</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QColor</span> <span class="cm-variable">borderColor</span>; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//边框颜色</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QColor</span> <span class="cm-variable">bgColor</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//背景颜色</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QRect</span> <span class="cm-variable">rect</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//矩形区域</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QPainterPath</span> <span class="cm-variable">path</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">//路径集合</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QList</span><span class="cm-operator">&lt;</span><span class="cm-variable">QPoint</span><span class="cm-operator">&gt;</span> <span class="cm-variable">points</span>; &nbsp; &nbsp; &nbsp; <span class="cm-comment">//点坐标集合</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">GraphInfo</span>() {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">name</span> <span class="cm-operator">=</span> <span class="cm-string">"graph"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">borderWidth</span> <span class="cm-operator">=</span> <span class="cm-number">2</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">borderColor</span> <span class="cm-operator">=</span> <span class="cm-string">"#FF0000"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">bgColor</span> <span class="cm-operator">=</span> <span class="cm-variable">QColor</span>(<span class="cm-number">255</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span>, <span class="cm-number">100</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">};</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">public</span> <span class="cm-variable">slots</span>:</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//设置图形</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">setGraph</span>(<span class="cm-keyword">const</span> <span class="cm-variable">GraphInfo</span> <span class="cm-operator">&amp;</span><span class="cm-variable">graph</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//添加图形</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">appendGraph</span>(<span class="cm-keyword">const</span> <span class="cm-variable">GraphInfo</span> <span class="cm-operator">&amp;</span><span class="cm-variable">graph</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//删除图形</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">removeGraph</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">name</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">27</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//清空图形</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">28</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">void</span> <span class="cm-def">clearGraph</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">29</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">30</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">DeviceVideoSmart::receiveRects</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QList</span><span class="cm-operator">&lt;</span><span class="cm-variable">QRect</span><span class="cm-operator">&gt;</span> <span class="cm-operator">&amp;</span><span class="cm-variable">rects</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">31</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">32</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-operator">!</span><span class="cm-variable">widget</span> <span class="cm-operator">||</span> <span class="cm-operator">!</span><span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">getIsRunning</span>()) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">33</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">return</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">34</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">35</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">36</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">clearGraph</span>();</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">37</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">foreach</span> (<span class="cm-variable">QRect</span> <span class="cm-variable">rect</span>, <span class="cm-variable">rects</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">38</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">GraphInfo</span> <span class="cm-variable">graph</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">39</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">graph</span>.<span class="cm-variable">borderColor</span> <span class="cm-operator">=</span> <span class="cm-variable">QColor</span>(<span class="cm-number">255</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">40</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">graph</span>.<span class="cm-variable">borderWidth</span> <span class="cm-operator">=</span> <span class="cm-number">3</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">41</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">graph</span>.<span class="cm-variable">rect</span> <span class="cm-operator">=</span> <span class="cm-variable">rect</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">42</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">widget</span><span class="cm-operator">-&gt;</span><span class="cm-variable">appendGraph</span>(<span class="cm-variable">graph</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">43</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">44</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 1014px;"></div><div class="CodeMirror-gutters" style="height: 1014px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><h3 id='216-预置巡航'><span>2.16 预置巡航</span></h3><p><span> </span><img src="snap/2-16-1.jpg" referrerpolicy="no-referrer"></p><p><span>操作步骤：</span></p><ol start='' ><li><p><span>左侧选中通道，前提是该通道的设备支持预置位，一般是球机才有预置位。</span></p></li><li><p><span>单击获取预置位，所有预置位信息会表格形式显示，每个预置位有唯一编号和名称，名称可以修改，编号改不了。</span></p></li><li><p><span>预置位表格中三个按钮依次为执行、更新、删除。</span></p></li><li><p><span>单击执行按钮（三角形状），会调用对应的预置位，设备会切换到对应预置位对应的位置。</span></p></li><li><p><span>单击更新按钮（加号形状），将当前设备停留的位置作为新的位置更新对应预置位。</span></p></li><li><p><span>单击删除按钮（删除形状），将当前选中的预置位信息删除，有部分设备仅仅是删除位置信息，预置位还会在，具体要看设备的支持。</span></p></li><li><p><span>输入预置位名称，调整画面到要新加的预置位置，单击添加预置位按钮，会新增加一个预置位。</span></p></li><li><p><span>调用起始位，一般是球机的默认开机后的位置，原始位置，单击调用起始位按钮后，会自动切换过去。</span></p></li><li><p><span>设置起始位，将当前位置设置为起始位置。</span></p></li></ol><h3 id='217-标签信息'><span>2.17 标签信息</span></h3><p><span> </span><img src="snap/2-17-1.jpg" referrerpolicy="no-referrer"></p><p><span>操作步骤：</span></p><ol start='' ><li><p><span>左侧选中通道，前提是该通道的设备支持OSD的onvif协议设置，一般大厂的都会支持。</span></p></li><li><p><span>单击获取OSD，所有OSD的唯一标识自动列在列表框中。</span></p></li><li><p><span>选中一个OSD，会自动获取该OSD的详细信息然后填入在下面，比如坐标位置、字体大小、标签类型等。</span></p></li><li><p><span>单击添加OSD，会将填写好的对应唯一标识的OSD添加到设备中，一般摄像头会限制OSD的数量，如果已经存在了很多OSD，有可能添加会失败，很多设备会限制最大支持4个OSD。</span></p></li><li><p><span>添加OSD的时候未必是按照填写的唯一标识来添加，设备一般按照自己的命名规则，所以该字段默认即可，比如海康的OSD标识都是OsdToken_开头。</span></p></li><li><p><span>修改OSD，一般支持的修改字段是坐标位置和文字内容，当然这两个也基本上是最常用的需要修改的字段，一般设备不支持将日期时间类型的OSD修改成文字文本类型的OSD，可以选择删除再添加的方式来实现。</span></p></li><li><p><span>很多设备会限制只支持1个日期时间的OSD和多个文字文本的OSD，所以如果你添加多个日期时间OSD的时候，可能会失败。</span></p></li><li><p><span>单击删除OSD会将当前选中的OSD删除，删除后会重新读取所有OSD信息。</span></p></li><li><p><span>在左侧通道上按下鼠标，会自动将鼠标按下处的位置对应的真实像素坐标发送到坐标位置文本框中，以便添加和修改OSD。</span></p></li></ol><h2 id='3-视频回放'><span>3 视频回放</span></h2><p><span>视频回放中有多个子模块，分别是不同的含义：</span></p><ol start='' ><li><p><span>本地回放：回放存储在本地电脑的视频文件。</span></p></li><li><p><span>远程回放：通过sdk方式回放NVR上的存储录像（暂未实现，每个厂家不一样）。</span></p></li><li><p><span>设备播放：通用的rtsp取流形式的播放实时视频和回放录像文件，支持海康大华等厂家的NVR回放。</span></p></li><li><p><span>图片回放：查找对应文件夹下的所有通道图片，按照设定的间隔回复，类似视频效果，一般用在存储一堆图片序列的应用场景中。</span></p></li><li><p><span>视频上传：将查询的本地存储的视频文件上传到云端服务器。类似于将视频文件存储到服务器上，需要手动填写服务器地址和端口。</span></p></li></ol><h3 id='31-本地回放'><span>3.1 本地回放</span></h3><h4 id='311-视频查询'><span>3.1.1 视频查询</span></h4><p><span> </span><img src="snap/3-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>基本步骤：</span></p><ol start='' ><li><p><span>选择设备通道（可以所有通道后者某个通道）。</span></p></li><li><p><span>选择视频类型（存储视频/报警视频），目前只有存储视频。</span></p></li><li><p><span>选择时间范围，考虑都范围大文件数量过多，默认限定查询60天内范围的视频。</span></p></li><li><p><span>单击查询按钮，符合条件的视频文件都会列出来，双击可以播放。</span></p></li><li><p><span>每个文件前面都有复选框，可以勾选用于下载和删除。</span></p></li><li><p><span>单击下载按钮，会将当前选中的文件拷贝到选择的目录。</span></p></li><li><p><span>单击删除按钮，会将当前选中的文件删除。</span></p></li><li><p><span>单击清空按钮，会将所有查询出来的文件全部删除。</span></p></li><li><p><span>播放过程中实时显示播放进度，可以单击或者拖动进度条切换进度。</span></p></li><li><p><span>默认播放完成一个会自动播放下一个，如果有下一个的话。</span></p></li><li><p><span>进度条左侧显示当前播放时长和文件总时长。</span></p></li><li><p><span>进度条右侧有三个按钮，分别是播放/暂停按钮、停止按钮、静音切换按钮。</span></p></li><li><p><span>右上角可以选择播放速度，播放过程中也会立即应用，可选0.5倍速、1.0倍速、2.0倍速、4.0倍速、8.0倍速等。</span></p></li></ol><h4 id='312-存储规则'><span>3.1.2 存储规则</span></h4><p><span> </span><img src="snap/3-1-2.jpg" referrerpolicy="no-referrer"></p><ol start='' ><li><p><span>默认存储主目录 video_normal。</span></p></li><li><p><span>主目录下按照日期目录存放(2025-10-01/2025-10-31)。</span></p></li><li><p><span>日期目录下是单个视频文件(ch01_2021-04-07-14-08-11.mp4/ch02_2021-04-07-14-08-11.mp4)。</span></p></li><li><p><span>拓展功能可以存储对应的数据文件比如经纬度数据和视频文件一个目录(名称一样并且拓展名可以是txt)。</span></p></li></ol><h3 id='32-远程回放'><span>3.2 远程回放</span></h3><p><span> </span><img src="snap/3-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>远程回放模块是用来通过sdk的形式回放远程NVR设备上的录像文件，</span><strong><span>这个暂未实现</span></strong><span>，本系统主要是为了兼容性和通用性，通过具体sdk形式调用的处理都没有做，破坏了移植性，到了其他平台就没法使用了。</span></p><h3 id='33-设备播放'><span>3.3 设备播放</span></h3><p><span> </span><img src="snap/3-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备播放模块主要是通过rtsp视频流的形式来拉取实时视频和回放视频，现在越来越多的NVR支持直接通过取流的形式来拉取实时视频流和回放视频，这样使用起来很方便，当然在拉取视频流的时候要传入用户信息，防止非法获取，现在越来越多的应用场景需要通过NVR来调取回放视频，传统的SDK的方式非常累厂家太多，而国标的形式太繁琐复杂，于是rtsp形式的最简单的方式应运而生，目前支持的厂家也越来越多，每个厂家格式的规则不一样，可以自行咨询厂家的规则，本程序默认实现了海康、大华的规则。</span></p><p><span>基本步骤：</span></p><ol start='' ><li><p><span>选择设备厂家，不同厂家rtsp视频流格式不一样，内置支持了海康、大华、通用的。</span></p></li><li><p><span>选择视频类型，支持实时视频和回放视频两种，回放视频还要选择时间范围。</span></p></li><li><p><span>填写用户名称、用户密码，最后组成rtsp视频流字符串一起。</span></p></li><li><p><span>填写或者下拉选择设备地址，填写IP地址，默认会把录像机管理中添加的设备地址填充到下拉框。</span></p></li><li><p><span>选择设备通道，一个设备比如NVR可能有多个通道，摄像机一般只有1个通道。</span></p></li><li><p><span>选择码流类型，可以选择主码流、子码流、三码流。</span></p></li><li><p><span>选择时间范围，实时视频不用选，回放视频才需要。</span></p></li><li><p><span>左侧选中某个通道，单击播放按钮，会将对应参数组成的rtsp视频流地址打开。</span></p></li><li><p><span>单击删除按钮，相当于关闭选中的通道。</span></p></li><li><p><span>可以单击暂停和继续两个按钮用来控制暂停播放和继续播放。由于是视频流是实时的，所以暂停期间会正常接收数据，但是并不会解码，所以当你再次播放时已经是最新的当前时间的视频数据。</span></p></li></ol><h3 id='34-图片回放'><span>3.4 图片回放</span></h3><h4 id='341-图片查询'><span>3.4.1 图片查询</span></h4><p><span> </span><img src="snap/3-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>选择设备通道和时间范围，单击查询按钮，会将查询到的图片序列按照日期的形式作为一行添加到列表结果中，双击可以自动播放，可以调节播放速度。</span></p><h4 id='342-存储规则'><span>3.4.2 存储规则</span></h4><p><span> </span><img src="snap/3-4-2.jpg" referrerpolicy="no-referrer"></p><ol start='' ><li><p><span>默认存储主目录 image_normal</span></p></li><li><p><span>主目录下按照日期目录存放(2025-10-01/2025-10-31)</span></p></li><li><p><span>日期目录下是单个图片文件(ch01_2021-04-07-14-08-11-222.jpg/ch02_2021-04-07-14-08-11-333.jpg)</span></p></li><li><p><span>拓展功能可以存储对应的数据文件比如警情文字和图片文件一个目录(名称一样并且拓展名可以是txt)</span></p></li></ol><h4 id='343-导出报告'><span>3.4.3 导出报告</span></h4><p><span> </span><img src="snap/3-4-3.jpg" referrerpolicy="no-referrer"></p><p><span>图文混排，可以自定义信息，封装好的类，传入图片队列，图片自适应等比例缩放显示，超过自动分页。</span></p><h3 id='35-视频上传'><span>3.5 视频上传</span></h3><p><span> </span><img src="snap/3-5-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/3-5-2.jpg" referrerpolicy="no-referrer"></p><p><span>视频上传功能主要用来将本地存储的视频文件（也可以是其他文件），通过网络传输（默认TCP）上传到其他地方比如服务器，服务器上要运行接收文件的程序，这样就相当于远程备份视频文件的功能，视频文件可以勾选需要上传哪一些。</span></p><h4 id='351-本地设置'><span>3.5.1 本地设置</span></h4><p><span>本地只需要在视频监控系统客户端上切换到视频上传页面，然后选择要查询的日期范围，单击查询，会将视频文件查询出来显示在左边的表格中，可以勾选要上传的视频文件，右侧填写好服务器的IP和端口（默认6000），单击上传按钮，会多线程的形式上传文件。</span></p><h4 id='352-远程设置'><span>3.5.2 远程设置</span></h4><p><span>远程需要放置文件传输工具，该工具完整源码如果购买了视频监控系统，可以赠送，该工具同时具备了发送端和接收端的功能，配套视频监控系统使用的是接收端，视频监控系统作为发送端，填好监听端口后，单击监听按钮，一旦有连接文件上传，会自动显示对应的接收进度，文件名称以上传的文件名为准。</span></p><h4 id='353-文件加密'><span>3.5.3 文件加密</span></h4><p><span>默认文件传输过程采用了加密机制，意味着传输的数据是加密后的数据，接收到以后根据设置的秘钥进行解密重新生成文件，防止文件传输过程中被拦截，可自定义加密规则。</span></p><h4 id='354-功能特点'><span>3.5.4 功能特点</span></h4><ol start='' ><li><p><span>多线程收发文件，支持加密传输。</span></p></li><li><p><span>接收端支持监听端口接收文件和主动连接服务器接收文件两种方式。</span></p></li><li><p><span>按照 文件开始符+文件大小+文件内容+文件结束符 逐个分包接收。</span></p></li><li><p><span>可对接收的加密过的文件包进行解密输出。</span></p></li><li><p><span>如果采用连接服务器方式接收文件可指定请求文件。</span></p></li><li><p><span>接收端请求文件的形式可以作为通用的程序升级方案。</span></p></li><li><p><span>进度条实时更新收发文件的进度。</span></p></li><li><p><span>发送端可设置每个包最很大小即切片分包数量。</span></p></li><li><p><span>发送端可对文件的每个包进行加密传输。</span></p></li><li><p><span>发送端支持对包进行合并发送。</span></p></li><li><p><span>可指定目录对客户端发来的请求文件进行搜索。</span></p></li><li><p><span>每个功能独立的一个类，接口清晰友好，使用方便。</span></p></li><li><p><span>支持任意Qt版本、任意系统、任意编译器。</span></p></li></ol><h2 id='4-电子地图'><span>4 电子地图</span></h2><p><span>电子地图有多个子模块，分别不同的功能，在每个模块上，双击对应的摄像机，都可以弹出实时视频预览画面，支持多个画面同时打开，每个摄像机都一个画面窗体。</span></p><ol start='' ><li><p><span>图片地图：摄像机分布在平面图上。</span></p></li><li><p><span>离线地图：默认采用百度离线瓦片地图，本地使用。</span></p></li><li><p><span>在线地图：默认采用百度地图，需要联网使用。</span></p></li><li><p><span>路径规划：指定起始点和终点经纬度坐标，查询最优路径并绘制路线，提取路线坐标集合，动态模拟轨迹，比如机器人和飞机轨迹。</span></p></li></ol><h3 id='41-双击预览'><span>4.1 双击预览</span></h3><p><span> </span><img src="snap/4-1-1.jpg" referrerpolicy="no-referrer"></p><h3 id='42-图片地图'><span>4.2 图片地图</span></h3><p><span> </span><img src="snap/4-2-1.jpg" referrerpolicy="no-referrer"></p><ol start='' ><li><p><span>图片地图的功能是为了方便直接提供图片文件，然后摄像机点位可直接拖动，更精确定位的场景，图片可以提供鸟瞰图这种，看起来更直观大气，有3D的感觉。</span></p></li><li><p><span>图片文件存放在可执行文件下的map文件夹下，如果需要增加或者删除，可以直接文件操作即可，比如复制新的图片文件到这个目录下即可。</span></p></li><li><p><span>具体摄像机对应哪张图片，可以在摄像机管理中设置，对应字段为地图，直接下拉选择对应的地图即可，默认选择无，就是该摄像机不属于任何地图。</span></p></li></ol><h3 id='43-离线地图'><span>4.3 离线地图</span></h3><p><span> </span><img src="snap/4-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>功能和在线地图完全一致，唯一区别就是地图是离线的，不需要联网。离线的地图需要自己准备好，可以网上通过瓦片地图下载器来下载需要的地方的离线地图，一般离线地图比较大，他是一张张图片，所以建议离线地图只下载自己需要的即可，比如某个县的地图，而不是所有的，所有的起码有几十GB。</span></p><p><strong><span>使用说明</span></strong></p><ol start='' ><li><p><span>默认系统提供的是上海市的地图。</span></p></li><li><p><span>下载地址在下面文章中，会自动更新地址。</span>
<a href='https://blog.csdn.net/feiyangqingyun/article/details/104005917' target='_blank' class='url'>https://blog.csdn.net/feiyangqingyun/article/details/104005917</a></p></li><li><p><span>请下载同目录下的bin_map_tiles.zip压缩包，解压到config目录下，最后config文件夹下会多出来tiles tiles_hybrid两个文件夹。</span></p></li></ol><h3 id='44-在线地图'><span>4.4 在线地图</span></h3><p><span> </span><img src="snap/4-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>在摄像机管理的界面，可以添加经纬度信息，这样就可以在地图上显示对应的摄像机点位信息，如果发现位置不对，可以在右侧先选择摄像机设备，然后鼠标单击新的位置，右侧目标经度、目标纬度信息会自动更新，然后再单击更新经纬度值则会更新当前下拉选择的设备的经纬度信息，也可以在摄像机管理界面手动填入进行修改。</span></p><p><span>在右侧还有模拟运动轨迹、开始显示轨迹两个按钮，有可能后期还会增加其他功能，是为了演示如何在地图上实现地图的相关功能，开始显示轨迹采用的定时器来生成轨迹点数据，动态模拟运动轨迹，可以单击显示设备位置按钮还原最初的设备点位图。</span></p><p><strong><span>功能特点</span></strong></p><ol start='' ><li><p><span>同时支持在线地图和离线地图两种模式。</span></p></li><li><p><span>同时支持webkit内核、webengine内核、IE内核。</span></p></li><li><p><span>支持设置多个标注点，信息包括名称、地址、经纬度。</span></p></li><li><p><span>可设置地图是否可单击、拖动、鼠标滚轮缩放。</span></p></li><li><p><span>可设置协议版本、秘钥、主题样式、中心坐标、中心城市、地理编码位置等。</span></p></li><li><p><span>可设置地图缩放比例和级别，缩略图、比例尺、路况信息等控件的可见。</span></p></li><li><p><span>支持地图交互，比如鼠标按下获取对应位置的经纬度。</span></p></li><li><p><span>支持查询路线，可设置起点位置、终点位置、路线模式、路线方式、路线方案（最少时间、最少换乘、最少步行、不乘地铁、最短距离、避开高速）。</span></p></li><li><p><span>可显示点线面工具，可直接在地图上划线、点、矩形、圆形等。</span></p></li><li><p><span>可设置行政区划，指定某个城市区域绘制图层，在线地图自动输出行政区划边界点集合到js文件给离线地图使用。</span></p></li><li><p><span>可静态或者动态添加多个覆盖物。支持点、折线、多边形、矩形、圆形、弧线、点聚合等。</span></p></li><li><p><span>函数接口友好和统一，使用简单方便，就一个类。</span></p></li><li><p><span>支持js动态交互添加点、删除点、清空点、重置点，不需要刷新页面。</span></p></li><li><p><span>支持任意Qt版本、任意系统、任意编译器。</span></p></li></ol><h3 id='45-路径规划'><span>4.5 路径规划</span></h3><p><span> </span><img src="snap/4-5-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>基本步骤</span></strong></p><ol start='' ><li><p><span>输入起点坐标和终点坐标，也可以勾选地图选点，开启后直接在左侧的地图界面鼠标按下自动识别对应的经纬度坐标填入，单选框勾选的起点则填入起点坐标输入框中，勾选的终点就填入终点坐标输入框中。</span></p></li><li><p><span>选择路线方式，可选公交、驾车、步行、骑行等方式，默认选择步行。</span></p></li><li><p><span>选择路线方案，可选最少时间、最短距离、避开高速等。</span></p></li><li><p><span>输入关键点数，一般查询返回的路径的经纬度坐标点数非常密集，可能非常多，我们需要根据输入的关键点数来过滤，比如输入30，表示从所有经纬度数据中平均提取出来30个数据就行。点数合计，查询路线后自动返回所有经纬度坐标的数据个数。</span></p></li><li><p><span>单击查询路线，自动返回对应路径的所有经纬度坐标。</span></p></li><li><p><span>单击帅选数据，按照填入的关键点数进行数据帅选，在下方可以看到原始数据和最终数据，选中某个数据，自动在左侧生成点预览对应的位置。</span></p></li><li><p><span>单击模拟轨迹，会启动定时器，从第一个数据点开始，自动移动设备比如机器人、飞行器等，查看整个轨迹点路径是否正确。</span></p></li></ol><h2 id='5-日志查询'><span>5 日志查询</span></h2><h3 id='51-本地日志'><span>5.1 本地日志</span></h3><p><span> </span><img src="snap/5-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本地日志存放的是本系统的操作日志，比如用户登录退出、记录删除、设备报警等操作，都会有对应的记录存放的数据库，可以在这里选择时间段和日志类型进行查询。查询后的日志记录可以翻页查看，还可以直接支持指定页码跳转，（此翻页组件超级牛逼，外观和功能分离，自动计算页码切换导航，具体可参见对应类的头文件功能描述），每页显示多少条记录在系统设置中可以设置。</span></p><h4 id='511-查询记录'><span>5.1.1 查询记录</span></h4><ol start='' ><li><p><span>可以按照多条件进行查询记录。</span></p></li><li><p><span>可以选择设备通道。</span></p></li><li><p><span>可以选择日志的类型：用户操作、运行日志、设备日志、报警日志。</span></p></li><li><p><span>可以选择时间范围。</span></p></li><li><p><span>在查询记录的时候，如果勾选了前面的复选框则表示启用该选择条件进行查询。</span></p></li><li><p><span>没有勾选，就算后面选择了类型等，也是按照where 1=1 条件查询的。</span></p></li><li><p><span>查询后的记录会自动分页显示，而不是一次性显示。</span></p></li><li><p><span>可以单击底部的翻页按钮进行翻页查看记录。</span></p></li><li><p><span>可以快速切换到第一页、末一页、上一页、下一页、显示的页码切换、指定的页码切换。</span></p></li></ol><h4 id='512-打印记录'><span>5.1.2 打印记录</span></h4><p><span> </span><img src="snap/5-1-2.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮，会将当前查询的记录打印出来，自动分页。打印前会弹出打印预览对话框，可以最后在这里调整边距、纸张等设置参数。</span></p><h4 id='513-导出记录到xls'><span>5.1.3 导出记录到xls</span></h4><p><span> </span><img src="snap/5-1-3.jpg" referrerpolicy="no-referrer"></p><p><span>单击XLS按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h4 id='514-导出记录到pdf'><span>5.1.4 导出记录到pdf</span></h4><p><span> </span><img src="snap/5-1-4.jpg" referrerpolicy="no-referrer"></p><h4 id='515-删除记录'><span>5.1.5 删除记录</span></h4><p><span> </span><img src="snap/5-1-5.jpg" referrerpolicy="no-referrer"></p><p><span>单击删除按钮，会弹出时间范围选择对话框，选择要删除的记录的开始时间和结束时间，单击确定，会将该时间段内的记录全部删除，结束时间必须大于开始时间。</span></p><h4 id='516-清空记录'><span>5.1.6 清空记录</span></h4><p><span>单击清空按钮会先弹出询问框提示是否需要清空数据，单击确定则自动清空所有的记录，清空后不能恢复。</span></p><h3 id='52-设备日志'><span>5.2 设备日志</span></h3><p><span> </span><img src="snap/5-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备日志是指直接通过sdk协议，远程从NVR设备上拉取日志记录到本地显示，其余功能和本地日志一致，此功能未实现。</span></p><h2 id='6-系统设置'><span>6 系统设置</span></h2><h3 id='61-基本设置'><span>6.1 基本设置</span></h3><p><span> </span><img src="snap/6-1-0.jpg" referrerpolicy="no-referrer"></p><h4 id='611-常规设置'><span>6.1.1 常规设置</span></h4><p><span> </span><img src="snap/6-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>基本设置中有部分参数的切换会自动重启应用。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>开机运行：开启以后自动随着系统启动运行，默认开启。</span></p></li><li><p><span>自动登录：开启以后会自动以最后登录的用户信息登录到系统，默认关闭。</span></p></li><li><p><span>记住密码：开启以后会自动填入最后登录的用户信息到登录窗体，默认关闭。</span></p></li><li><p><span>中文标题：软件左上角标题栏的中文标题，改动立即应用。</span></p></li><li><p><span>英文标题：软件左上角标题栏的英文标题，改动立即应用。</span></p></li><li><p><span>版权所有：当前软件版权所有的公司，目前没有显示在哪里，备用。</span></p></li><li><p><span>调试日志：开启后会将打印日志输出到日志文件，默认关闭，日志文件存放在可执行文件夹下的log目录下。</span></p></li><li><p><span>运行时间：开启后会实时记录系统的运行时间，记录当前软件启动后运行了多久，运行时间文件存放在可执行文件夹下的log目录下。</span></p></li><li><p><span>工作模式：默认视频监控，可选机器人监控、无人机监控等。</span></p></li><li><p><span>导航样式：用于选择顶部导航栏和左侧导航栏的样式，上侧+左侧表示顶部导航栏上侧样式（图标在上面，文字在下面），左侧导航栏左侧样式（图标在左侧，文字在右侧）。</span></p></li><li><p><span>界面样式：系统自带17套皮肤，可以在这里自动换肤，默认视频黑。</span></p></li><li><p><span>软件图标：自动从logo文件夹读取，可以自行选择对应的logo文件。</span></p></li><li><p><span>全屏模式：开启以后，最大化显示自动全屏显示而不是最大化显示，默认关闭。</span></p></li><li><p><span>弹框时间：右下角弹出提示信息自动关闭时间，0秒表示常驻不关闭。</span></p></li><li><p><span>报警声音：0表示不启用，其余表示报警后播放的声音次数。</span></p></li><li><p><span>鼠标隐藏：主界面多久鼠标没有操作过会自动隐藏鼠标指针，一般在全屏轮询的时候需要设置，效果会更好。</span></p></li><li><p><span>自动全屏：经过多久以后鼠标没有操作过自动全屏，0表示不启用。</span></p></li><li><p><span>播放记录：如果开启在软件打开后会自动读取上一次的播放记录并自动打开，不需要可以关闭。</span></p></li><li><p><span>图文警情：图文警情模块消息行数，0表示自动计算填满，不产生滚动条。</span></p></li><li><p><span>窗口消息：窗口消息模块消息行数，0表示自动计算填满，不产生滚动条。</span></p></li><li><p><span>透明度值：停靠窗体的透明度值，可调节，动态应用。</span></p></li></ol><h4 id='612-视频参数'><span>6.1.2 视频参数</span></h4><p><span> </span><img src="snap/6-1-2.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>共享解码：开启后相同地址的通道会复用之前已经打开的通道，这样可以大大节省网络流量和解码压力。</span></p></li><li><p><span>播放音频：开启以后可以播放声音，有时候不需要声音的时候可以关闭，节省资源。</span></p></li><li><p><span>保存视频：录像计划的总开关，开启以后自动存储录像文件，目录在可执行文件目录video_normal。</span></p></li><li><p><span>事件订阅：开启以后会用onvif的机制订阅报警事件。</span></p></li><li><p><span>自动校时：开启后摄像机上线立即同步本地时间到设备。</span></p></li><li><p><span>人工智能：用于演示绘制osd标签和添加各种图形绘制到视频图片上。</span></p></li><li><p><span>画面显示：可选自动调整、等比缩放、拉伸填充三种图片显示策略。</span></p></li><li><p><span>显示模式：可选句柄、绘制、GPU三种模式，在ffmpeg内核下句柄和GPU都是同一种处理。</span></p></li><li><p><span>硬件加速：会根据不同的内核以及不同的系统自动显示不同的可用的加速器名称，默认none表示不启用硬件加速，ffmpeg可选dxva2和d3d11va，建议用dxva2。</span></p></li><li><p><span>通信方式：视频流采用何种通信方式，默认TCP（可靠连接，不会丢包，缺点就是慢），可选UDP（不可靠连接，容易丢包，但是速度快）。</span></p></li><li><p><span>解码策略：ffmpeg内核专用，可选速度优先、质量优先、均衡处理、最快速度，如果对实时视频流rtsp有实时性要求建议选择最快速度，可以看到无论是打开加载视频流还是响应都是最快的。</span></p></li><li><p><span>缓存大小：vlc内核专用，值越小响应速度越快，受限于网络环境和硬件性能。</span></p></li><li><p><span>读取超时：读取视频流过程的超时时间，可选不处理或者具体的秒数，不处理则一直等待直到系统层通知读取失败，选择的话可以加快速度跳出并立即通知失败，建议设置5s，在网络环境不好或者网络中断的情况下能够快速识别到掉线。</span></p></li><li><p><span>连接超时：对于视频流地址可用，先探测对应的地址是否通，不通则不用继续，加载很慢的一些网络地址需要把时间设置大一些，可以尝试用vlc等第三方播放器打开地址对比速度，如果确实很慢，这个值可以设置大一些。</span></p></li><li><p><span>分组双击：可选最后空白通道、从头清空通道，就是双击设备父节点的时候，是从哪个通道开始打开，如果选择的是最后空白通道，则会从通道1开始遍历找到第一个空白的通道依次打开，如果选择的是从头清空通道，则每次都是全部清空再从通道1开始打开。</span></p></li><li><p><span>设备双击：可选最后空白通道、最后按下通道，就是双击设备子节点的时候，是在哪个通道打开视频，如果选择的是最后空白通道，则会从通道1开始遍历找到第一个空白的通道打开视频，如果选择的是最后按下通道，则对按下的通道先删除再打开视频。</span></p></li><li><p><span>表格策略：摄像机管理中，对应表格是按下进入编辑状态还是双击进入编辑状态。</span></p></li><li><p><span>视频边框：视频控件边框大小，用户根据实际需要选择即可。</span></p></li></ol><h4 id='613-数据库设置'><span>6.1.3 数据库设置</span></h4><p><span> </span><img src="snap/6-1-3.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>远程同步：开启后将会启用云端数据同步功能，将本地数据实时同步到远程数据库中。</span></p></li><li><p><span>主机类型：和本地数据库设置一样，可选多种。</span></p></li><li><p><span>数据库名：对应数据库的数据库名称，一个数据库系统中可以有多个数据库实例。</span></p></li><li><p><span>主机地址：数据库所在的网络地址，可以是IP地址或者网址。</span></p></li><li><p><span>通信端口：数据库开放通信的端口，不同数据库默认端口不同，比如mysql是3306，postgres是5432，sqlserver是1433。</span></p></li><li><p><span>用户名称：登录到网络数据库对应的用户名称，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></p></li><li><p><span>用户密码：登录到网络数据库对应的用户密码，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></p></li><li><p><span>连接测试：单击后主动连接一次当前填入的数据库信息，连接成功与失败都会弹框提示。</span></p></li><li><p><span>初始数据：单击后会执行sql脚本文件，重置数据库，会将原来的数据一并清空。务必记得只有需要的时候才执行。</span></p></li></ol><p><strong><span>其他说明</span></strong></p><ol start='' ><li><p><span>默认提供了数据库脚本文件（源码下的file/db/video_system.sql）。</span></p></li><li><p><span>单击初始化数据按钮可以对整个数据库进行新建和重置，相当于恢复出厂。</span></p></li><li><p><span>系统支持多种数据库，默认sqlite（Qt内置的数据库，无需安装），可选mysql、postgresql、oracle、人大金仓等。</span></p></li><li><p><span>具体还需要对应Qt版本有数据库插件支持，没有插件支持可以自行编译对应缺失的插件比如mysql，也可选直接通过万能的ODBC来连接。</span></p></li><li><p><span>除了sqlite数据库外，其余数据库都需要输入数据库名称、主机地址、通信端口、用户名称、用户密码信息，输入好以后可以单击连接测试按钮测试下是否正常。</span></p></li><li><p><span>默认提供的是mysql的动态库libmysql.dll，需要放到可执行文件同一目录，严格区分32位和64位的动态库。</span></p></li></ol><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>38</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//数据库类型枚举</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">enum</span> <span class="cm-def">DbType</span> {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_ODBC</span> <span class="cm-operator">=</span> <span class="cm-number">0</span>, &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">//odbc数据源</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Sqlite</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>, &nbsp; &nbsp; &nbsp;<span class="cm-comment">//sqlite数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_MySql</span> <span class="cm-operator">=</span> <span class="cm-number">2</span>, &nbsp; &nbsp; &nbsp; <span class="cm-comment">//mysql数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_PostgreSQL</span> <span class="cm-operator">=</span> <span class="cm-number">3</span>, &nbsp;<span class="cm-comment">//postgresql数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_SqlServer</span> <span class="cm-operator">=</span> <span class="cm-number">4</span>, &nbsp; <span class="cm-comment">//sqlserver数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Oracle</span> <span class="cm-operator">=</span> <span class="cm-number">5</span>, &nbsp; &nbsp; &nbsp;<span class="cm-comment">//oracle数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_KingBase</span> <span class="cm-operator">=</span> <span class="cm-number">6</span>, &nbsp; &nbsp;<span class="cm-comment">//人大金仓数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Other</span> <span class="cm-operator">=</span> <span class="cm-number">255</span> &nbsp; &nbsp; &nbsp;<span class="cm-comment">//其他数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">};</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//自动切换默认数据库端口</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">DbHelper::getDbDefaultInfo</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">dbType</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">hostPort</span>,</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">userName</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">userPwd</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"MYSQL"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"3306"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"SQLSERVER"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"1433"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"sa"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"POSTGRESQL"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"5432"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">27</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"postgres"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">28</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">29</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"ORACLE"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">30</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"1521"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">31</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"system"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">32</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">33</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"KINGBASE"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">34</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"54321"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">35</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"SYSTEM"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">36</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">37</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">38</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 875px;"></div><div class="CodeMirror-gutters" style="height: 875px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><h4 id='614-地图配置'><span>6.1.4 地图配置</span></h4><p><span> </span><img src="snap/6-1-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>地图秘钥：对应百度地图的秘钥，默认内置的作者的秘钥，很多软件系统都用的这个秘钥，用户数较多，可能有并发限制，为了不影响体验，强烈建议改成自己的，可以自行去官网申请，免费。</span></p></li><li><p><span>地图中心：默认地图的中心点坐标。</span></p></li><li><p><span>地图级别：默认地图打开以后的缩放级别。</span></p></li></ol><h4 id='615-功能激活'><span>6.1.5 功能激活</span></h4><p><span> </span><img src="snap/6-1-5.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>勾选则表示启用。</span></p></li><li><p><span>可以对各种分屏进行功能激活。</span></p></li><li><p><span>需要重启应用。</span></p></li><li><p><span>没有勾选的，不会显示对应的菜单切换和分屏快捷按钮。</span></p></li><li><p><span>多个子界面模块也可以选择显示或者隐藏，以便将不需要的模块隐藏掉，碍眼。</span></p></li></ol><h4 id='616-颜色配置'><span>6.1.6 颜色配置</span></h4><p><span> </span><img src="snap/6-1-6.jpg" referrerpolicy="no-referrer"></p><p><span>可以设置不同的场景不同的颜色，比如正常的系统消息显示白色，异常消息红色。</span></p><h3 id='62-录像机管理'><span>6.2 录像机管理</span></h3><p><span> </span><img src="snap/6-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统所用的录像机信息，并没有实际的作用，也就是不一定要填写实际的录像机信息，留作备用后期使用，目前仅仅是作为生成设备的树状列表使用（类似于区域或分组），如果一个录像机都没有填写，则会自动生成一个默认的录像机信息。</span></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><p><span>设备编号：录像机的编号，唯一字段。</span></p></li><li><p><span>设备名称：录像机的别名，建议不要重复。</span></p></li><li><p><span>设备类型：录像机的厂家类型，可选海康、大华、宇视、其他等。</span></p></li><li><p><span>设备地址：录像机的IP地址。</span></p></li><li><p><span>用户姓名：录像机的登录用户名称。</span></p></li><li><p><span>用户密码：录像机的登录用户密码。</span></p></li><li><p><span>启用状态：录像机设备是否启用。</span></p></li><li><p><span>安装位置：录像机的安装位置。</span></p></li></ol><h4 id='621-录像机添加'><span>6.2.1 录像机添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='622-录像机删除'><span>6.2.2 录像机删除</span></h4><p><span>如果要删除某个录像机信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='623-录像机清空'><span>6.2.3 录像机清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='624-录像机信息导入'><span>6.2.4 录像机信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='625-录像机信息导出'><span>6.2.5 录像机信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='626-录像机信息打印'><span>6.2.6 录像机信息打印</span></h4><p><span> </span><img src="snap/6-2-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='627-导出到excel'><span>6.2.7 导出到Excel</span></h4><p><span> </span><img src="snap/6-2-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h3 id='63-摄像机管理'><span>6.3 摄像机管理</span></h3><p><span> </span><img src="snap/6-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>摄像机表信息，是整个系统中最核心的表，这里管理的所有的摄像机信息，并不是所有的字段都显示出来了，比如onvif地址、云台地址等都是隐藏的，因为无需添加更改，需要搜索自动添加的。</span></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><p><span>设备编号：摄像机的唯一编号。</span></p></li><li><p><span>设备名称：摄像机的别名，建议不要重复。</span></p></li><li><p><span>录 像 机：该摄像机对应所属的录像机，随便选择一个就行。</span></p></li><li><p><span>设备厂家：摄像机的厂家类型，通过onvif搜索会自动有厂家信息，没有的就选择其他。</span></p></li><li><p><span>主码流地址：摄像机的主码流地址。</span></p></li><li><p><span>子码流地址：摄像机的子码流地址。</span></p></li><li><p><span>经 纬 度：摄像机的经纬度信息，用来地图上显示位置，中间用 | 隔开。</span></p></li><li><p><span>背景地图：摄像机对应的平面地图，下拉选择，默认从可执行文件下的map目录下读取图片文件列表生成。</span></p></li><li><p><span>用户姓名：摄像机登录的用户名称。</span></p></li><li><p><span>用户密码：摄像机登录的用户密码。</span></p></li><li><p><span>启用状态：摄像机是否启用。</span></p></li><li><p><span>安装位置：摄像机的安装位置。</span></p></li></ol><h4 id='631-摄像机添加'><span>6.3.1 摄像机添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='632-摄像机删除'><span>6.3.2 摄像机删除</span></h4><p><span>如果要删除某个摄像机信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='633-摄像机清空'><span>6.3.3 摄像机清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='634-摄像机信息导入'><span>6.3.4 摄像机信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='635-摄像机信息导出'><span>6.3.5 摄像机信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。</span></p><h4 id='636-摄像机信息打印'><span>6.3.6 摄像机信息打印</span></h4><p><span> </span><img src="snap/6-3-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='637-导出到excel'><span>6.3.7 导出到Excel</span></h4><p><span> </span><img src="snap/6-3-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h4 id='638-设备搜索'><span>6.3.8 设备搜索</span></h4><p><span> </span><img src="snap/6-3-8.jpg" referrerpolicy="no-referrer"></p><p><span>如果摄像机已经添加过，则搜索出来的摄像机对应行禁用不可选中。</span></p><p><strong><span>基本步骤</span></strong></p><ul><li><p><span>第一步：单击广播搜索按钮，搜索到的设备会显示在左侧表格中。</span></p></li><li><p><span>第二步：输入onvif用户名和密码，注意是onvif的用户信息，一个摄像机可能有多种用户，比如登录用户，远程用户，onvif用户，务必记得要用onvif用户信息，可参阅说明书的末尾 </span><a href='#13-其他说明'><span>海康大华onvif设置</span></a><span>。</span></p></li><li><p><span>第三步：单击获取所有，会自动以填写的onvif用户信息，去拉取具体摄像机的码流地址、云台地址等信息，可以拉动底部的横向滚动条查看具体是否获取到信息。</span></p></li><li><p><span>第四步：单击添加选中按钮将所有勾选了复选框的设备添加到摄像机信息表中。</span></p></li></ul><p><strong><span>特别说明</span></strong></p><ol start='' ><li><p><span>如果没有码流地址，是添加不了的，必须有码流地址才能添加。</span></p></li><li><p><span>一般一个项目上的摄像机都是同一个品牌的，onvif用户信息也都一样，所以单击获取所有可以把所有摄像机的信息获取到。</span></p></li><li><p><span>可以填入不同的onvif用户信息，单击获取当前按钮来指定摄像机获取onvif信息。</span></p></li><li><p><span>如果有些设备不支持广播，只支持单播（比如不是同一网段的设备，但是路由器设置过，是通的），则指定设备右侧填写好IP地址或者onvif地址，再单击单播搜索即可。</span></p></li><li><p><span>一台电脑可能多个网卡和IP网段，可以选择不同的网卡进行搜索，相当于不同的网段。</span></p></li><li><p><span>录像机信息和摄像机信息的更改，是自动应用的，无需重启。</span></p></li><li><p><span>搜索后的设备信息自动添加到表格中，按照IP地址升序排序，支持跨网段排序，自动将IP地址转为quint32整型进行排序，而不是取IP地址末尾。</span></p></li></ol><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>用户姓名：onvif用户的名称，默认admin。</span></p></li><li><p><span>用户密码：onvif用户的密码，默认admin。</span></p></li><li><p><span>选择网卡：选择对应电脑的网卡IP，可能有多个网段，onvif只能同一个网段。</span></p></li><li><p><span>指定设备：对指定的IP地址或者onvif地址进行onvif搜索。</span></p></li><li><p><span>过滤设备：对返回的onvif地址进行过滤，一种厂家的类别的设备地址格式一样。</span></p></li><li><p><span>搜索间隔：默认onvif搜索指令有好几种，会重发几次，指定发送的间隔。</span></p></li><li><p><span>搜索策略：默认自动清空，每次都重新添加搜索到的设备，如果选择设备累加则多次搜索后只会将新增加的设备加到设备列表，这个非常有用，在很多设备现场建议用设备累加策略而不是自动清空，因为onvif协议是udp协议，在大量数据的情况下会导致丢包，需要多次搜索，取最终的设备集合。</span></p></li><li><p><span>广播搜索：广播搜索指定网卡的所有onvif设备。</span></p></li><li><p><span>单播搜索：对指定设备进行单个搜索。</span></p></li><li><p><span>获取所有：按照当前填入的用户姓名和密码，填充到onvif请求鉴权中对所有搜索的设备进行媒体地址的获取、云台控制地址的获取、视频流地址的获取等。</span></p></li><li><p><span>获取当前：很多时候并不是所有的设备onvif用户信息一样，对于不一样的，可以先选中设备所在行，然后输入不同的用户信息，单击获取当前即可，会对当前选中的设备重新获取onvif信息。</span></p></li><li><p><span>添加选中：搜索到的设备前面都有个复选框，单击添加选中以后会对所有打钩的设备批量添加到摄像机信息表中，会自动过滤已经添加过的设备以及没有视频流地址的设备。</span></p></li><li><p><span>添加当前：对应获取当前，一般来说单个添加用户信息不一样的设备，因为批量添加不了，他的信息需要单独获取。</span></p></li></ol><h3 id='64-轮询配置'><span>6.4 轮询配置</span></h3><p><span> </span><img src="snap/6-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>轮询点管理界面，上侧是轮询点信息表，可以直接添加、删除、修改、清空轮询点信息，下侧是摄像机信息表，会自动加载，当摄像机信息变动后，这里会自动加载最新的数据。右下角是批量生成轮询点和轮询分组管理。</span></p><h4 id='641-轮询点添加'><span>6.4.1 轮询点添加</span></h4><p><span>轮询点的添加有三种方式：手动添加、单个添加、批量添加。允许重复添加，没有过滤机制。</span></p><p><strong><span>添加方式</span></strong></p><ol start='' ><li><p><span>手动添加：单击添加按钮，在右侧轮询信息表格中自动生成默认轮询点信息，手动输入和修改信息然后单击保存按钮即可。</span></p></li><li><p><span>单个添加：左侧摄像机信息表中选中一行，单击添加当前按钮，会将选中的摄像机信息添加到右侧轮询点信息中，自动保存。</span></p></li><li><p><span>批量添加：单击添加所有按钮，会将所有摄像机信息添加到右侧轮询点信息中，自动保存。</span></p></li></ol><h4 id='642-轮询点删除'><span>6.4.2 轮询点删除</span></h4><p><span>如果要删除某个轮询点信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='643-轮询点清空'><span>6.4.3 轮询点清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='644-轮询点信息导入'><span>6.4.4 轮询点信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='645-轮询点信息导出'><span>6.4.5 轮询点信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。</span></p><h4 id='645-轮询点信息打印'><span>6.4.5 轮询点信息打印</span></h4><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='647-导出到excel'><span>6.4.7 导出到Excel</span></h4><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h4 id='648-参数设置'><span>6.4.8 参数设置</span></h4><p><span> </span><img src="snap/6-4-8.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>自动轮询：开启以后，启动软件后自动轮询。</span></p></li><li><p><span>轮询间隔：画面切换的间隔，单位秒，建议时间长一点。</span></p></li><li><p><span>轮询画面：轮询的画面数，可选1画面、4画面、9画面、16画面。</span></p></li><li><p><span>码流类型：默认子码流，超过4画面建议子码流。</span></p></li></ol><h4 id='649-批量生成'><span>6.4.9 批量生成</span></h4><p><span> </span><img src="snap/6-4-9.jpg" referrerpolicy="no-referrer"></p><p><span>轮询表信息可以通过已添加的摄像机信息表选中添加，也可以自定义规则批量生成视频流地址添加，这种应用场景非常多，比如现场是某一种品牌的摄像机，视频流格式固定，只需要设置好主码流子码流的视频流格式，便可批量生成。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><p><span>生成数量： 需要批量生成多少个。</span></p></li><li><p><span>起始地址：如果选择的是文件，则填写对应的数字，其他则填写IP地址。</span></p></li><li><p><span>地址格式：可选各种厂家类型，还可选择文件，这个用于测试软件非常有用。</span></p></li></ol><h4 id='6410-分组设置'><span>6.4.10 分组设置</span></h4><p><span> </span><img src="snap/6-4-10.jpg" referrerpolicy="no-referrer"></p><p><span>可添加、删除、修改、清空轮询分组名称，相当于轮询预案。</span></p><h3 id='65-用户管理'><span>6.5 用户管理</span></h3><p><span> </span><img src="snap/6-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>用户管理是后面增加的一个模块，用于设置不同的用户不同的类型+权限，可以细分到每个模块的权限，勾选表示具有该权限，内置了7种权限选择，后期还可以在此基础上增加其他权限等。</span></p><h4 id='651-用户添加'><span>6.5.1 用户添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='652-用户删除'><span>6.5.2 用户删除</span></h4><p><span>如果要删除某个用户信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。不允许删除内置的admin用户。</span></p><h4 id='653-用户清空'><span>6.5.3 用户清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='654-用户信息导入'><span>6.5.4 用户信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='655-用户信息导出'><span>6.5.5 用户信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。</span></p><h4 id='656-用户信息打印'><span>6.5.6 用户信息打印</span></h4><p><span> </span><img src="snap/6-5-6.jpg" referrerpolicy="no-referrer">
<span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='657-导出到excel'><span>6.5.7 导出到Excel</span></h4><p><span> </span><img src="snap/6-5-7.jpg" referrerpolicy="no-referrer">
<span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h4 id='658-权限验证'><span>6.5.8 权限验证</span></h4><p><span> </span><img src="snap/6-5-8-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/6-5-8-2.jpg" referrerpolicy="no-referrer"></p><p><span>假设设置了用户没有退出系统和电子地图的权限，则关闭系统的时候会弹出错误信息提示当前用户没有权限。</span></p><h3 id='66-录像计划'><span>6.6 录像计划</span></h3><p><span> </span><img src="snap/6-6-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/6-6-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/6-6-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/6-6-4.jpg" referrerpolicy="no-referrer"></p><p><span>录像文件严格按照30分钟一个文件，除了首个文件和末尾文件不一定是30分钟的文件，中间的肯定是完整的30分钟的文件，时间从00:00到29:59或者30:00到59:59。由于文件打开和保存需要时间以及保证首帧是关键帧（有些设备可以设置I帧间隔50/意味着接近2s一个关键帧），文件可能会有1-2s的偏差。</span></p><p><span>基本步骤：</span></p><ol start='' ><li><p><span>单击批量按钮可以批量添加1-64通道7 * 24小时录像计划到数据库中。</span></p></li><li><p><span>每个通道可以设置周一到周日7天的每个半小时时段是否录像。</span></p></li><li><p><span>上面表格中选中通道，下面录像计划控件选择对应的格子即可。</span></p></li><li><p><span>可以鼠标右键选择全选、反选、清空操作。</span></p></li><li><p><span>录像计划控件更改后会立即更新表格中对应通道的录像计划值，1表示该时间段录像，0表示不录像。</span></p></li><li><p><span>选中通道表格行，下面会自动显示对应的录像计划，一目了然。</span></p></li></ol><h3 id='67-其他设置'><span>6.7 其他设置</span></h3><p><span> </span><img src="snap/6-7-0.jpg" referrerpolicy="no-referrer"></p><p><span>其他设置里面的内容之前在基本设置中，现在重新开一个窗体，因为后面可能还有各种各样的设置，预留空间。</span></p><h4 id='661-串口配置'><span>6.6.1 串口配置</span></h4><p><span> </span><img src="snap/6-7-1.jpg" referrerpolicy="no-referrer"></p><p><span>系统中可能用到了多个串口通信，可以在这里选择对应的串口号和波特率。</span></p><h4 id='662-网络配置'><span>6.6.2 网络配置</span></h4><p><span> </span><img src="snap/6-7-2.jpg" referrerpolicy="no-referrer"></p><p><span>系统中可能用到多种网络通信，比如软件主动连接服务器，需要填写TCP地址和端口，也可能软件作为服务端，填写TCP或者UDP监听端口。</span></p><h2 id='7-简易使用步骤'><span>7 简易使用步骤</span></h2><h3 id='71-添加摄像机'><span>7.1 添加摄像机</span></h3><ol start='' ><li><p><span>切换到系统设置-》摄像机管理，单击添加，输入码流地址，单击保存。如果不知道码流地址，需要通过onvif搜索，具体参见 </span><a href='#638-设备搜索'><span>6.3.8 设备搜索</span></a><span> ，有非常详细的步骤。</span></p></li><li><p><span>在不知道主码流和子码流是啥的情况下，两个地方填一样的，其余默认即可。</span></p></li><li><p><span>本地文件格式：g:/mp4/1.mp4</span></p></li><li><p><span>USB摄像机：默认ffmpeg内核为 video=USB2.0 PC CAMERA</span></p></li><li><p><span>摄像机视频流：直接填入rtsp、rtmp、http的视频流地址，该地址可以先用vlc播放器或者potplay等播放器先试试是否能正常播放，不能的话就别添加了，添加了也没卵用，别费力气了。</span></p></li></ol><h3 id='72-视频播放'><span>7.2 视频播放</span></h3><p><span>切换到视频监控主界面，左侧设备列表，双击摄像机，自动通道播放，双击录像机则整个录像机下面的摄像机全部加载。</span></p><h3 id='73-云台控制'><span>7.3 云台控制</span></h3><p><span>云台控制的前提是摄像机是通过onvif搜索的形式添加的，不然没有云台地址没法进行云台控制，当然也必须要求摄像机带云台，不带云台的摄像机是不能进行云台控制的。</span>
<span>先选中要进行云台控制的摄像机通道，边缘高亮，然后再单击右侧的云台控件，可以上下左右等移动，变倍和光圈没有用。</span></p><h3 id='74-自动校时'><span>7.4 自动校时</span></h3><p><span>在系统设置中开启自动校时后，设备自动上线后会自动将本地时间同步到设备。</span></p><h3 id='75-事件订阅'><span>7.5 事件订阅</span></h3><p><span>在系统设置中开启事件订阅后，一旦接收到设备的报警信息会显示到主界面左下角的信息栏，右下角弹出对应的报警信息。</span>
<span>摄像机要响应事件订阅，具体详细设置说明参见说明书其他说明中的摄像机报警输入设置。</span></p><h3 id='76-图片参数'><span>7.6 图片参数</span></h3><p><span> </span><img src="snap/7-6-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>操作说明</span></strong></p><ul><li><p><span>用onvif也可以对摄像机的明亮度、对比度、饱和度进行设置。</span></p></li><li><p><span>先选中对应的通道，然后右下角这里找到设置的区域。</span></p></li><li><p><span>单击获取参数，会自动将对应摄像机的明亮度、对比度、饱和度值读回来，显示在对应文本框和滑块中。</span></p></li><li><p><span>如果需要设置图片参数，先移动滑块到需要的值，然后单击设置参数按钮即可。</span></p></li><li><p><span>设置完以后会立即应用，传过来的视频流就能看到效果。</span></p></li><li><p><span>下面还有两个按钮可以手动重启设备以及校时。后期可能还会增加一些按钮。</span></p></li></ul><h2 id='8-内核模块说明'><span>8 内核模块说明</span></h2><ol start='' ><li><p><span>本系统支持多种内核，方便不同的用户选择，适应不同的应用场景。</span></p></li><li><p><strong><span>本系统默认集成的是ffmpeg内核，其他内核需要额外购买或者定制，支持定制内核。</span></strong></p></li><li><p><span>每个内核实现的功能不一定完全一致（可能受限于对应组件源头本身的功能缺失），推荐用默认的ffmpeg内核。</span></p></li></ol><h3 id='81-视频监控内核'><span>8.1 视频监控内核</span></h3><h4 id='811-效果图'><span>8.1.1 效果图</span></h4><p><span> </span><img src="snap/8-1-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-4.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-5.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-6.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-1-7.jpg" referrerpolicy="no-referrer"></p><h4 id='812-基础功能'><span>8.1.2 基础功能</span></h4><ol start='' ><li><p><span>支持各种音频视频文件格式，比如mp3、wav、mp4、asf、rm、rmvb、mkv等。</span></p></li><li><p><span>支持本地摄像头设备和本地桌面采集，支持多设备和多屏幕。</span></p></li><li><p><span>支持各种视频流格式，比如rtp、rtsp、rtmp、http、udp等。</span></p></li><li><p><span>本地音视频文件和网络音视频文件，自动识别文件长度、播放进度、音量大小、静音状态等。</span></p></li><li><p><span>文件可以指定播放位置、调节音量大小、设置静音状态等。</span></p></li><li><p><span>支持倍速播放文件，可选0.5倍、1.0倍、2.5倍、5.0倍等速度，相当于慢放和快放。</span></p></li><li><p><span>支持开始播放、停止播放、暂停播放、继续播放。</span></p></li><li><p><span>支持抓拍截图，可指定文件路径，可选抓拍完成是否自动显示预览。</span></p></li><li><p><span>支持录像存储，手动开始录像、停止录像，部分内核支持暂停录像后继续录像，跳过不需要录像的部分。</span></p></li><li><p><span>支持无感知切换循环播放、自动重连等机制。</span></p></li><li><p><span>提供播放成功、播放完成、收到解码图片、收到抓拍图片、视频尺寸变化、录像状态变化等信号。</span></p></li><li><p><span>多线程处理，一个解码一个线程，不卡主界面。</span></p></li></ol><h4 id='813-特色功能'><span>8.1.3 特色功能</span></h4><ol start='' ><li><p><span>同时支持多种解码内核，包括qmedia内核（Qt4/Qt5/Qt6）、ffmpeg内核（ffmpeg2/ffmpeg3/ffmpeg4/ffmpeg5/ffmpeg6）、vlc内核（vlc2/vlc3）、mpv内核（mpv1/mp2）、mdk内核、海康sdk、easyplayer内核等。</span></p></li><li><p><span>非常完善的多重基类设计，新增一种解码内核只需要实现极少的代码量，就可以应用整套机制，极易拓展。</span></p></li><li><p><span>同时支持多种画面显示策略，自动调整（原始分辨率小于显示控件尺寸则按照原始分辨率大小显示，否则等比缩放）、等比缩放（永远等比缩放）、拉伸填充（永远拉伸填充）。所有内核和所有视频显示模式下都支持三种画面显示策略。</span></p></li><li><p><span>同时支持多种视频显示模式，句柄模式（传入控件句柄交给对方绘制控制）、绘制模式（回调拿到数据后转成QImage用QPainter绘制）、GPU模式（回调拿到数据后转成yuv用QOpenglWidget绘制）。</span></p></li><li><p><span>支持多种硬件加速类型，ffmpeg可选dxva2、d3d11va等，vlc可选any、dxva2、d3d11va，mpv可选auto、dxva2、d3d11va，mdk可选dxva2、d3d11va、cuda、mft等。不同的系统环境有不同的类型选择，比如linux系统有vaapi、vdpau，macos系统有videotoolbox。</span></p></li><li><p><span>解码线程和显示窗体分离，可指定任意解码内核挂载到任意显示窗体，动态切换。</span></p></li><li><p><span>支持共享解码线程，默认开启并且自动处理，当识别到相同的视频地址，共享一个解码线程，在网络视频环境中可以大大节约网络流量以及对方设备的推流压力。国内顶尖视频厂商均采用此策略。这样只要拉一路视频流就可以共享到几十个几百个通道展示。</span></p></li><li><p><span>自动识别视频旋转角度并绘制，比如手机上拍摄的视频一般是旋转了90度的，播放的时候要自动旋转处理，不然默认是倒着的。</span></p></li><li><p><span>自动识别视频流播放过程中分辨率的变化，在视频控件上自动调整尺寸。比如摄像机可以在使用过程中动态配置分辨率，当分辨率改动后对应视频控件也要做出同步反应。</span></p></li><li><p><span>音视频文件无感知自动切换循环播放，不会出现切换期间黑屏等肉眼可见的切换痕迹。</span></p></li><li><p><span>视频控件同时支持任意解码内核、任意画面显示策略、任意视频显示模式。</span></p></li><li><p><span>视频控件悬浮条同时支持句柄、绘制、GPU三种模式，非绝对坐标移来移去。</span></p></li><li><p><span>本地摄像头设备支持指定设备名称、分辨率、帧率进行播放。</span></p></li><li><p><span>本地桌面采集支持设定采集区域、偏移值、指定桌面索引、帧率、多个桌面同时采集等。</span></p></li><li><p><span>录像文件同时支持打开的视频文件、本地摄像头、本地桌面、网络视频流等。</span></p></li><li><p><span>瞬间响应打开和关闭，无论是打开不存在的视频或者网络流，探测设备是否存在，读取中的超时等待，收到关闭指令立即中断之前的操作并响应。</span></p></li><li><p><span>支持打开各种图片文件，支持本地音视频文件拖曳播放。</span></p></li><li><p><span>视频流通信方式可选tcp/udp，有些设备可能只提供了某一种协议通信比如tcp，需要指定该种协议方式打开。</span></p></li><li><p><span>可设置连接超时时间（视频流探测用的超时时间）、读取超时时间（采集过程中的超时时间）。</span></p></li><li><p><span>支持逐帧播放，提供上一帧/下一帧函数接口，可以逐帧查阅采集到的图像。</span></p></li><li><p><span>音频文件自动提取专辑信息比如标题、艺术家、专辑、专辑封面，自动显示专辑封面。</span></p></li><li><p><span>视频响应极低延迟0.2s左右，极速响应打开视频流0.5s左右，专门做了优化处理。</span></p></li><li><p><span>支持H264/H265编码（现在越来越多的监控摄像头是H265视频流格式）生成视频文件，内部自动识别切换编码格式。</span></p></li><li><p><span>支持用户信息中包含特殊字符（比如用户信息中包含+#@等字符）的视频流播放，内置解析转义处理。</span></p></li><li><p><span>支持滤镜，各种水印及图形效果，支持多个水印和图像，可以将OSD标签信息和各种图形信息写入到MP4文件。</span></p></li><li><p><span>支持视频流中的各种音频格式，AAC、PCM、G.726、G.711A、G.711Mu、G.711ulaw、G.711alaw、MP2L2等都支持，推荐选择AAC兼容性跨平台性最好。</span></p></li><li><p><span>内核ffmpeg采用纯qt+ffmpeg解码，非sdl等第三方绘制播放依赖，gpu绘制采用qopenglwidget，音频播放采用qaudiooutput。</span></p></li><li><p><span>内核ffmpeg和内核mdk支持安卓，其中mdk支持安卓硬解码，性能非常凶残。</span></p></li><li><p><span>可以切换音视频轨道，也就是节目通道，可能ts文件带了多个音视频节目流，可以分别设置要播放哪一个，可以播放前设置好和播放过程中动态设置。</span></p></li><li><p><span>可以设置视频旋转角度，可以播放前设置好和播放过程中动态设置。</span></p></li><li><p><span>视频控件悬浮条自带开始和停止录像切换、声音静音切换、抓拍截图、关闭视频等功能。</span></p></li><li><p><span>音频组件支持声音波形值数据解析，可以根据该值绘制波形曲线和柱状声音条，默认提供了声音振幅信号。</span></p></li><li><p><span>标签和图形信息支持三种绘制方式，绘制到遮罩层、绘制到图片、源头绘制（对应信息可以存储到文件）。</span></p></li><li><p><span>通过传入一个url地址，该地址可以带上通信协议、分辨率、帧率等信息，无需其他设置。</span></p></li><li><p><span>保存视频到文件支持三种策略，自动处理、仅限文件、全部转码，转码策略支持自动识别、转264、转265，编码保存支持指定分辨率缩放或者等比例缩放。比如对保存文件体积有要求可以指定缩放后再存储。</span></p></li><li><p><span>支持加密保存文件和解密播放文件，可以指定秘钥文本。</span></p></li><li><p><span>支持电子放大，在悬浮条切换到电子放大模式，在画面上选择需要放大的区域，选取完毕后自动放大，再次切换放大模式可以复位。</span></p></li><li><p><span>各组件中极其详细的打印信息提示，尤其是报错信息提示，封装的统一打印格式。针对现场复杂的设备环境测试极其方便有用，相当于精确定位到具体哪个通道哪个步骤出错。</span></p></li><li><p><span>同时提供了简单示例、视频播放器、多画面视频监控、监控回放、逐帧播放、多屏渲染等单独窗体示例，专门演示对应功能如何使用。</span></p></li><li><p><span>代码框架和结构优化到最优，性能强悍，持续迭代更新升级。</span></p></li><li><p><span>源码支持Qt4、Qt5、Qt6，兼容所有版本。</span></p></li></ol><h4 id='814-视频控件'><span>8.1.4 视频控件</span></h4><ol start='' ><li><p><span>可动态添加任意多个osd标签信息，标签信息包括名字、是否可见、字号大小、文本文字、文本颜色、背景颜色、标签图片、标签坐标、标签格式（文本、日期、时间、日期时间、图片）、标签位置（左上角、左下角、右上角、右下角、居中、自定义坐标）。</span></p></li><li><p><span>可动态添加任意多个图形信息，这个非常有用，比如人工智能算法解析后的图形区域信息直接发给视频控件即可。图形信息支持任意形状，直接绘制在原始图片上，采用绝对坐标。</span></p></li><li><p><span>图形信息包括名字、边框大小、边框颜色、背景颜色、矩形区域、路径集合、点坐标集合等。</span></p></li><li><p><span>每个图形信息都可指定三种区域中的一种或者多种，指定了的都会绘制。</span></p></li><li><p><span>内置悬浮条控件，悬浮条位置支持顶部、底部、左侧、右侧。</span></p></li><li><p><span>悬浮条控件参数包括边距、间距、背景透明度、背景颜色、文本颜色、按下颜色、位置、按钮图标代码集合、按钮名称标识集合、按钮提示信息集合。</span></p></li><li><p><span>悬浮条控件一排工具按钮可自定义，通过结构体参数设置，图标可选图形字体还是自定义图片。</span></p></li><li><p><span>悬浮条按钮内部实现了录像切换、抓拍截图、静音切换、关闭视频等功能，也可以自行在源码中增加自己对应的功能。</span></p></li><li><p><span>悬浮条按钮对应实现了功能的按钮，有对应图标切换处理，比如录像按钮按下后会切换到正在录像中的图标，声音按钮切换后变成静音图标，再次切换还原。</span></p></li><li><p><span>悬浮条按钮单击后都用名称唯一标识作为信号发出，可以自行关联响应处理。</span></p></li><li><p><span>悬浮条空白区域可以显示提示信息，默认显示当前视频分辨率大小，可以增加帧率、码流大小等信息。</span></p></li><li><p><span>视频控件参数包括边框大小、边框颜色、焦点颜色、背景颜色（默认透明）、文字颜色（默认全局文字颜色）、填充颜色（视频外的空白处填充黑色）、背景文字、背景图片（如果设置了图片优先取图片）、是否拷贝图片、缩放显示模式（自动调整、等比缩放、拉伸填充）、视频显示模式（句柄、绘制、GPU）、启用悬浮条、悬浮条尺寸（横向为高度、纵向为宽度）、悬浮条位置（顶部、底部、左侧、右侧）。</span></p></li></ol><h3 id='82-onvif搜索模块'><span>8.2 onvif搜索模块</span></h3><h4 id='821-效果图'><span>8.2.1 效果图</span></h4><p><span> </span><img src="snap/8-2-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-2-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-2-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/8-2-4.jpg" referrerpolicy="no-referrer"></p><h4 id='822-功能介绍'><span>8.2.2 功能介绍</span></h4><ol start='' ><li><p><span>广播搜索设备，支持IPC和NVR，依次返回。</span></p></li><li><p><span>可选择不同的网卡IP进行对应网段设备的搜索。</span></p></li><li><p><span>依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。</span></p></li><li><p><span>可对指定的Profile获取视频流Rtsp地址，比如主码流地址、子码流地址。</span></p></li><li><p><span>可对每个设备设置Onvif用户信息，用于认证获取详细信息。</span></p></li><li><p><span>可实时预览摄像机图像。</span></p></li><li><p><span>支持云台控制，可上下左右调节云台，支持绝对移动、相对移动、连续移动三种方式，可对图像拉近拉远。</span></p></li><li><p><span>支持获取预置位集合、调用预置位、添加预置位、删除预置位等。</span></p></li><li><p><span>支持图片参数设置，包括亮度、对比度、饱和度、锐度等。</span></p></li><li><p><span>支持Qt4和Qt6任意Qt版本以及后续Qt版本，亲测Qt4.7.0到Qt6.2。</span></p></li><li><p><span>支持任意编译器，亲测mingw、msvc、gcc、clang。</span></p></li><li><p><span>支持任意操作系统，亲测xp、win7、win10、android、linux、嵌入式linux、树莓派全志H3等。</span></p></li><li><p><span>支持任意Onvif摄像机和NVR，亲测海康、大华、宇视、天地伟业、华为、海思芯片内核等，可定制开发。</span></p></li><li><p><span>支持对指定IP地址及onvif地址进行单播搜索，比如跨网段情况下非常有用。</span></p></li><li><p><span>支持指定过滤条件过滤搜索设备。</span></p></li><li><p><span>支持搜索间隔和搜索策略设置，保证所有设备搜索回来，在大量设备现场很有用（亲测上千个摄像机现场，搜索回来的设备数量比摄像机厂家自带搜索工具还要准确）。</span></p></li><li><p><span>可对设备进行重启、网络参数获取等。</span></p></li><li><p><span>支持各种事件订阅、Onvif抓图等操作。</span></p></li><li><p><span>支持NTP校时和时间同步设置。</span></p></li><li><p><span>内置了线程实时执行Onvif指令队列，排队最大速度的执行对应的指令，执行结果信号发出。</span></p></li><li><p><span>采用的最底层的TCP+UDP通信机制，原创最底层协议解析，纯QtWidget编写。</span></p></li><li><p><span>超级小巧轻量，总共约3000行代码，不依赖任何第三方的库和组件，跨平台。</span></p></li><li><p><span>封装好了通用的数据发送和接收解析的函数，可以非常方便的自行拓展其他Onvif处理。</span></p></li><li><p><span>工具上提供了收发数据文本框，显示收发的数据，方便查看和分析。</span></p></li><li><p><span>支持所有Onvif设备，代码工整，接口友好，直接引入pri即可使用。</span></p></li></ol><h4 id='823-云台说明'><span>8.2.3 云台说明</span></h4><ol start='' ><li><p><span>x、y、z 范围都在0-1之间。</span></p></li><li><p><span>x为负数，表示左转，x为正数，表示右转。</span></p></li><li><p><span>y为负数，表示下转，y为正数，表示上转。</span></p></li><li><p><span>z为正数，表示拉近，z为负数，表示拉远。</span></p></li><li><p><span>通过x和y的组合，来实现云台的控制。</span></p></li><li><p><span>通过z的组合，来实现焦距控制。</span></p></li></ol><h4 id='824-主要功能'><span>8.2.4 主要功能</span></h4><ol start='' ><li><p><span>搜索设备，获取设备的信息比如厂家、型号等。</span></p></li><li><p><span>获取设备的多个配置文件信息profile。</span></p></li><li><p><span>获取对应配置文件的视频流地址rtsp，以及分辨率等参数。</span></p></li><li><p><span>云台控制，上下左右移动，焦距放大缩小，相对和绝对移动。</span></p></li><li><p><span>获取预置位信息，触发预置位。</span></p></li><li><p><span>订阅事件，接收设备的各种消息尤其是报警事件比如IO口的报警。</span></p></li><li><p><span>抓图，获取设备当前的图片。</span></p></li><li><p><span>获取、创建、删除用户信息。</span></p></li><li><p><span>获取和设备网络配置信息比如IP地址等。</span></p></li><li><p><span>获取和设置NTP时间同步。</span></p></li><li><p><span>获取和设置设备时间。</span></p></li><li><p><span>重启设备。</span></p></li></ol><h4 id='825-处理流程'><span>8.2.5 处理流程</span></h4><ol start='' ><li><p><span>绑定组播IP（239.255.255.250）和端口（3702），发送固定的xml格式的数据搜索设备。</span></p></li><li><p><span>接收到的xml格式的数据解析，得到设备的Onvif地址。</span></p></li><li><p><span>对Onvif地址发送对应的数据，收到数据取出对应的节点数据。</span></p></li><li><p><span>请求Onvif地址获取Media地址和Ptz地址，Media地址用来获取详细的配置文件，Ptz地址用来云台控制。</span></p></li><li><p><span>ptz控制是对Ptz地址发送对应的数据即可。</span></p></li><li><p><span>设置了用户认证的需要组织用户token信息一块发送，每次都需要作鉴权处理。</span></p></li><li><p><span>接收到的数据不是标准的xml数据，没法按照正常的节点解析来处理，只能用QXmlQuery来做。</span></p></li><li><p><span>每个厂家设备返回的数据未必完全一致，基本上都不一致，需要进行模糊查找节点值。</span></p></li><li><p><span>特意采用底层协议解析，因为soap太臃肿函数名称太另类，特意做的轻量级的。</span></p></li><li><p><span>两个必备工具，Onvif Device Manager 和 Onvif Device Test Tool。</span></p></li></ol><h3 id='83-gb28181处理模块'><span>8.3 gb28181处理模块</span></h3><p><span>暂未实现</span></p><h2 id='9-主界面模块说明'><span>9 主界面模块说明</span></h2><p><span>本系统主界面采用QMainWindow停靠窗体模式设计，这样可以自定义各种各样的子模块停靠悬浮等，不同的工作模式可以对应不同的模块，甚至可以拓展成不同的用户权限对应不同的主界面模块。所有子模块都是new出来的，支持任意多个。</span></p><h3 id='90-主界面'><span>9.0 主界面</span></h3><p><span>视频监控系统支持多种工作模式，不同的工作模式可以有不同的主界面、悬停模块、布局方案。互相不影响。悬停模块可以有透明度，更具科幻感。</span></p><h4 id='901-视频监控-普通模式'><span>9.0.1 视频监控-普通模式</span></h4><p><span> </span><img src="snap/9-0-1.jpg" referrerpolicy="no-referrer"></p><h4 id='902-视频监控-全屏模式'><span>9.0.2 视频监控-全屏模式</span></h4><p><span> </span><img src="snap/9-0-2.jpg" referrerpolicy="no-referrer"></p><h4 id='903-机器人监控-普通模式'><span>9.0.3 机器人监控-普通模式</span></h4><p><span> </span><img src="snap/9-0-3.jpg" referrerpolicy="no-referrer"></p><h4 id='904-机器人监控-全屏模式'><span>9.0.4 机器人监控-全屏模式</span></h4><p><span> </span><img src="snap/9-0-4.jpg" referrerpolicy="no-referrer"></p><h4 id='905-无人机监控-普通模式'><span>9.0.5 无人机监控-普通模式</span></h4><p><span> </span><img src="snap/9-0-5.jpg" referrerpolicy="no-referrer"></p><h4 id='906-无人机监控-全屏模式'><span>9.0.6 无人机监控-全屏模式</span></h4><p><span> </span><img src="snap/9-0-6.jpg" referrerpolicy="no-referrer"></p><h3 id='91-设备列表'><span>9.1 设备列表</span></h3><p><span> </span><img src="snap/9-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备列表通过读取录像机信息（生成父节点，相当于区域，录像机信息本身在整个系统中目前就一个作为设备列表的区域信息功能，用户可以自行拓展作为其他用途。）、摄像机信息，自动生成设备列表，每个摄像机都对应一个主码流和子码流，支持各种视频流、本地视频文件、USB摄像机等。</span></p><h3 id='92-窗口信息'><span>9.2 窗口信息</span></h3><p><span> </span><img src="snap/9-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>窗口信息负责显示一些打印信息，比如串口是否打开成功，摄像机是否异常，各种报警日志等，可以在系统设置中设置不同的文字颜色，窗口信息的信息条数自动计算应用，保证最大可能的适应高度。</span></p><h3 id='93-图文警情'><span>9.3 图文警情</span></h3><p><span> </span><img src="snap/9-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>图文警情模块负责以图文的形式显示对应的警情或者提示信息，有时间、内容、图片，双击对应图片可以放大查看具体图片，为了方便演示如何使用，在此模块增加了右键菜单，可以添加消息、删除消息、清空消息。</span></p><h3 id='94-云台控制'><span>9.4 云台控制</span></h3><p><span> </span><img src="snap/9-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>云台控制模块，可以对选中的通道的摄像机（ONVIF协议），进行云台控制，可以控制球机的上下左右等各个方位的移动，还可以调节变倍步长，至于变焦和光圈，目前onvif协议中没看到对应的协议支持，没有实现。</span></p><p><span>云台移动总共有3种策略：绝对移动、相对移动、连续移动，本系统都支持三种策略，默认采用的连续移动，这也是大部分应用场景需要的，按下对应的方位进行移动，松开立即停止移动，非常人性化。</span></p><h3 id='95-设备控制'><span>9.5 设备控制</span></h3><p><span> </span><img src="snap/9-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备控制模块，可以对选中的通道的摄像机（ONVIF协议），进行获取参数、设置参数、手动校时、重启设备、抓拍图片、模拟报警等操作，可以对摄像机的明亮度、对比度、饱和度进行设置。后期还可能不断增加新的功能。</span></p><h3 id='96-预置位置'><span>9.6 预置位置</span></h3><p><span> </span><img src="snap/9-6-1.jpg" referrerpolicy="no-referrer"></p><p><span>预置位功能，只对带有预置位的球机才起作用，有云台的球机未必有预置位，要仔细查看清楚，不清楚可以询问厂家或者查阅手册，在本模块中，可以获取预置位、添加预置位、调用预置位、删除预置位、调用起始位、设置起始位、开始巡航、停止巡航等。</span></p><p><span>获取预置位以后，会将获取到的预置位集合(一般有255个甚至更多)显示到列表中，前面是编号token，后面是预置位的别名name，别名可以是中文的，可以通过添加预置位的时候设置中文的名称。在每个预置位信息后面都有三个按钮：调用、添加、删除，直接单击即可执行相应的动作，拉伸子模块窗体对应名称列自动拉伸填充。</span></p><p><span>自动巡航目前采用的策略是通过勾选查询回来的预置位信息，勾选，然后定时器每隔一段时间调用一次对应的预置位来实现，每次正在执行哪个预置位会在列表中自动选中该预置位，后期如果有更好的处理方法会自动更新改进代码。</span></p><h3 id='97-巡航设置'><span>9.7 巡航设置</span></h3><p><span>目前放在预置位中，后期可能会有改动。</span></p><h3 id='98-悬浮地图'><span>9.8 悬浮地图</span></h3><p><span> </span><img src="snap/9-8-1.jpg" referrerpolicy="no-referrer"></p><p><span>悬浮地图子模块，使用的百度地图，支持在线和离线，用于显示对于设备的位置，支持鼠标直接拖动和缩放。具体和飞行轨迹模块类似。</span></p><h3 id='99-飞行轨迹'><span>9.9 飞行轨迹</span></h3><p><span> </span><img src="snap/9-9-1.jpg" referrerpolicy="no-referrer"></p><p><span>专为无人机打造的模块，也可以作为机器人移动模块，通过传入一个经纬度值，实时更新设备的位置和绘制轨迹，模块已经内置了接口进行处理，支持不同设备不同的轨迹颜色（这个功能好）。</span></p><h3 id='910-备用模块'><span>9.10 备用模块</span></h3><p><span>此模块留给用户自行填入内容。</span></p><h3 id='911-数据调试'><span>9.11 数据调试</span></h3><p><span> </span><img src="snap/9-11-1.jpg" referrerpolicy="no-referrer"></p><p><span>数据调试模块，用于显示通信串口的数据，自定义不同颜色显示，可以勾选过滤某个串口进行数据查看，也可以选择所有数据，还可以勾选暂停显示复选框用来暂停打印显示信息。</span></p><h3 id='912-运动仿真'><span>9.12 运动仿真</span></h3><p><span>此模块留给用户自行填入内容。</span></p><h3 id='913-图像增强'><span>9.13 图像增强</span></h3><p><span>此模块留给用户自行填入内容。</span></p><h3 id='914-网页浏览'><span>9.14 网页浏览</span></h3><p><span> </span><img src="snap/9-14-1.jpg" referrerpolicy="no-referrer"></p><p><span>网页浏览模块，用于传入一个网页地址，打开对应的网页进行浏览，可用于网页展示信息，支持多个，可以自行增加，代码中演示了一个。</span></p><h2 id='10-各系统运行图'><span>10 各系统运行图</span></h2><h3 id='100-样式风格'><span>10.0 样式风格</span></h3><p><span> </span><img src="snap/10-0-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-4.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-5.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-6.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-0-7.jpg" referrerpolicy="no-referrer"></p><p><span>本系统内置高达18+套皮肤样式供用户选择，可以在系统设置中随意切换立即应用。</span></p><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>26</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">GlobalStyle::getStyle</span>(<span class="cm-variable">QStringList</span> <span class="cm-operator">&amp;</span><span class="cm-variable">styleNames</span>, <span class="cm-variable">QStringList</span> <span class="cm-operator">&amp;</span><span class="cm-variable">styleFiles</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">static</span> <span class="cm-variable">QStringList</span> <span class="cm-variable">names</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">names</span>.<span class="cm-variable">count</span>() <span class="cm-operator">==</span> <span class="cm-number">0</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"黑蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"软件黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"视频黑"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深黑色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"深灰色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平蓝"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"扁平灰"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅黑色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"浅灰色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通黑"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通蓝"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"普通灰"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">names</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大蓝色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大紫色"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">"大银色"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">//中文皮肤名称对应样式表文件</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">static</span> <span class="cm-variable">QStringList</span> <span class="cm-variable">files</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">files</span>.<span class="cm-variable">count</span>() <span class="cm-operator">==</span> <span class="cm-number">0</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blackblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blacksoft.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/blackvideo.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/darkgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/flatgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/lightgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalblack.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/normalgray.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">files</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/otherblue.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/otherpurple.css"</span> <span class="cm-operator">&lt;&lt;</span> <span class="cm-string">":/qss/othersilvery.css"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">styleNames</span> <span class="cm-operator">=</span> <span class="cm-variable">names</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">styleFiles</span> <span class="cm-operator">=</span> <span class="cm-variable">files</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 599px;"></div><div class="CodeMirror-gutters" style="height: 599px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><h3 id='101-windows-7'><span>10.1 windows-7</span></h3><p><span> </span><img src="snap/10-1-1.jpg" referrerpolicy="no-referrer"></p><h3 id='102-windows-11'><span>10.2 windows-11</span></h3><p><span> </span><img src="snap/10-2-1.jpg" referrerpolicy="no-referrer"></p><h3 id='103-linux-ubuntu'><span>10.3 linux-ubuntu</span></h3><p><span> </span><img src="snap/10-3-1.jpg" referrerpolicy="no-referrer"></p><h3 id='104-linux-fedora'><span>10.4 linux-fedora</span></h3><p><span> </span><img src="snap/10-4-1.jpg" referrerpolicy="no-referrer"></p><h3 id='105-linux-centos'><span>10.5 linux-centos</span></h3><p><span> </span><img src="snap/10-5-1.jpg" referrerpolicy="no-referrer"></p><h3 id='106-linux-uos'><span>10.6 linux-uos</span></h3><p><span> </span><img src="snap/10-6-1.jpg" referrerpolicy="no-referrer"></p><h3 id='107-linux-kylin'><span>10.7 linux-kylin</span></h3><p><span> </span><img src="snap/10-7-1.jpg" referrerpolicy="no-referrer"></p><h3 id='108-linux-neokylin'><span>10.8 linux-neokylin</span></h3><p><span> </span><img src="snap/10-8-1.jpg" referrerpolicy="no-referrer"></p><h3 id='109-linux-newstart'><span>10.9 linux-newstart</span></h3><p><span> </span><img src="snap/10-9-1.jpg" referrerpolicy="no-referrer"></p><h3 id='1010-linux-debian'><span>10.10 linux-debian</span></h3><p><span> </span><img src="snap/10-10-1.jpg" referrerpolicy="no-referrer"></p><h3 id='1011-unix-mac'><span>10.11 unix-mac</span></h3><p><span> </span><img src="snap/10-11-1.jpg" referrerpolicy="no-referrer"></p><h2 id='11-程序框架说明'><span>11 程序框架说明</span></h2><p><span>备注：下面的截图和说明未必是最新的，但是大部分是一致的，整体的框架不会改变，可能会有新增加子模块和代码，或者部分类文件有调整或者删除，具体以最新的代码为准。</span></p><h3 id='111-整体代码结构'><span>11.1 整体代码结构</span></h3><p><span> </span><img src="snap/11-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统采用模块化的设备，有用到第三方开源类库比如串口通信qextserialport，全部放在3rd下面，有用到很多自己封装完善的通用类库比如ffmpeg视频监控，全部放在core下面，设备通信和辅助处理全部放在class下面，所有界面全部放在ui下面，相当于一个个小的组件合起来，最终形成了整个监控系统的完整代码。</span></p><h3 id='112-主模块说明'><span>11.2 主模块说明</span></h3><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd</span></td><td style='text-align:left;' ><span>一些第三方开源的类库，比如串口通信qextserialport。</span></td></tr><tr><td style='text-align:left;' ><span>class</span></td><td style='text-align:left;' ><span>存放系统初始化、样式控制、自定义控件、设备通信等。</span></td></tr><tr><td style='text-align:left;' ><span>core</span></td><td style='text-align:left;' ><span>本人一直持续更新完善的通用的类库，比如ffmpeg视频监控。</span></td></tr><tr><td style='text-align:left;' ><span>ui</span></td><td style='text-align:left;' ><span>所有的界面都分门别类放在这里。</span></td></tr></tbody></table></figure><h3 id='113-子模块说明'><span>11.3 子模块说明</span></h3><h4 id='1131-第三方类库'><span>11.3.1 第三方类库</span></h4><p><span> </span><img src="snap/11-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的全部是第三方开源的轮子，感谢开源、感谢github、gitee等开源社区。</span></p><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd_qextserialport</span></td><td style='text-align:left;' ><span>第三方串口通信qextserialport，这个类比较稳定可靠，经过了几十个项目持续数十年运行的考验，不用Qt自带的串口类。</span></td></tr></tbody></table></figure><p><span>具体代码不做过多说明。</span></p><h4 id='1132-通信及辅助类'><span>11.3.2 通信及辅助类</span></h4><p><span> </span><img src="snap/11-3-2.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的都是一些系统初始化、设备通信相关的类。</span></p><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>api</span></td><td style='text-align:left;' ><span>存放数据库表映射成对应的全局队列数据、通用的辅助函数类。</span></td></tr><tr><td style='text-align:left;' ><span>app</span></td><td style='text-align:left;' ><span>全局配置参数管理类、秘钥管理类、通用函数。</span></td></tr><tr><td style='text-align:left;' ><span>devicecustom</span></td><td style='text-align:left;' ><span>用户自定义设备通信管理，比如机器人通信、无人机通信等。</span></td></tr><tr><td style='text-align:left;' ><span>devicevideo</span></td><td style='text-align:left;' ><span>视频监控相关处理类，包括设备地图、表格消息、线程UI通信、人工智能处理等。</span></td></tr><tr><td style='text-align:left;' ><span>usercontrol</span></td><td style='text-align:left;' ><span>当前系统的自定义控件全部放在这里，其中包括云台仪表盘、天气面板等控件。</span></td></tr></tbody></table></figure><h5 id='11321-模块-api'><span>11.3.2.1 模块-api</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>dbdata</span></td><td style='text-align:left;' ><span>将数据库表映射到全局变量数据队列，比如将摄像机表ipcinfo转成QStringList存放一行行数据，这样在程序中运算比较速度极快，直接内存比较，不用每次都去读取数据库。</span></td></tr><tr><td style='text-align:left;' ><span>dbquery</span></td><td style='text-align:left;' ><span>所有的数据库查询插入更新等操作都在这里，比如查询摄像机表、插入日志记录等。</span></td></tr></tbody></table></figure><h5 id='11322-模块-app'><span>11.3.2.2 模块-app</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>appconfig</span></td><td style='text-align:left;' ><span>配置参数类，整个系统的配置参数存放在ini文件中，跨平台，所有参数都对应一个变量，读取配置参数的时候将值赋值给变量，写入的时候将变量值写入到配置文件。</span></td></tr><tr><td style='text-align:left;' ><span>appdata</span></td><td style='text-align:left;' ><span>全局变量类，系统中无可避免需要一些全局变量方便处理，都放在此类，比如版本号、录像机类型、摄像机类型、当前用户信息、地图宽度高度、左侧右侧顶部底部宽高等。</span></td></tr><tr><td style='text-align:left;' ><span>appevent</span></td><td style='text-align:left;' ><span>全局事件转发类，系统越复杂信号需要传递的层级越多，所以需要一个全局事件转发类，用来中转这些事件，这样永远只需要两层就可以收到信号进行处理，而且整个系统看起来干净整洁，不会说一个信号传递到了N个地方乱七八糟，建议需要跨层级传递的信号都放在这里中转。比如软件退出信号，可能多个界面需要收到退出信号进行保存和其他处理，如果从关闭界面发出信号传递给需要的界面，那不知道要中间层层传递多少次，有了这个全局事件转发类，你只需要将事件传给appevent，需要接收事件的地方关联这个信号就行，appevent为全局单例类，整个系统唯一。通用的一些信号有软件退出、全局样式改变、主窗体变化（0-最小化 1-最大化 2-恢复 3-关闭 4-移动 5-尺寸变化）等。</span></td></tr><tr><td style='text-align:left;' ><span>appinit</span></td><td style='text-align:left;' ><span>程序初始化类，在main函数中，会先执行这个初始化的类，比如初始化皮肤、字体、数据库、样式等操作，这些都是要优先在窗体加载前执行的，执行完毕以后再打开窗体主界面。</span></td></tr><tr><td style='text-align:left;' ><span>appstyle</span></td><td style='text-align:left;' ><span>全局样式管理类，整个系统的样式全部放在这里，一般加载流程是先读取样式表文件，然后将本系统独特的样式（比如开关按钮、视频监控、云台仪表盘）内容追加到后面，最后统一设置全局样式，在main函数中加载，和appinit类一样放在最前面执行。</span></td></tr><tr><td style='text-align:left;' ><span>appurl</span></td><td style='text-align:left;' ><span>视频监控系统中常用的默认的视频地址集合。</span></td></tr></tbody></table></figure><h5 id='11323-模块-devicecustom'><span>11.3.2.3 模块-devicecustom</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>devicerobot</span></td><td style='text-align:left;' ><span>机器人串口通信管理类。</span></td></tr><tr><td style='text-align:left;' ><span>devicerobot2</span></td><td style='text-align:left;' ><span>机器人串口通信管理类2，有串口数据转发功能。</span></td></tr><tr><td style='text-align:left;' ><span>deviceuavsserver</span></td><td style='text-align:left;' ><span>无人机后端服务类，当前为空，用户自己添加。</span></td></tr><tr><td style='text-align:left;' ><span>deviceuavsvideo</span></td><td style='text-align:left;' ><span>无人机视频监控类，将视频控件设置过来，然后就可以将自己人工智能算法处理后的图片传过来进行绘制，类似于实时视频效果。</span></td></tr></tbody></table></figure><h5 id='11324-模块-devicevideo'><span>11.3.2.4 模块-devicevideo</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>devicehelper</span></td><td style='text-align:left;' ><span>整个系统设备管理辅助类，比如插入窗口消息、加载设备列表、加载图片地图、加载设备按钮、初始化视频控件等。</span></td></tr><tr><td style='text-align:left;' ><span>devicemap</span></td><td style='text-align:left;' ><span>设备图片地图管理类，相当于一次性加载所有图片到内存，当要切换或者显示的时候，直接从内存取出来设置即可，速度极快，瞬间相应，纯粹是为了加快相应速度以及可能在图片上进行绘制增加的功能，比从文件系统读取图片文件显示快N倍。</span></td></tr><tr><td style='text-align:left;' ><span>deviceonvif</span></td><td style='text-align:left;' ><span>设备onvif通信管理类，比如获取当前选中通道的onvif地址、开启事件订阅、校对时间、重启设备、获取视频参数、设置视频参数、云台控制等，这里是具体的需要和摄像机信息表及视频通道关联的处理，所以不能放到通用的onvif模块中。</span></td></tr><tr><td style='text-align:left;' ><span>devicethreadui</span></td><td style='text-align:left;' ><span>演示线程通知UI更新，包括每隔一段时间插入消息、异步调用添加表格消息和图文警情、设备GPS移动、报警闪烁、指定通道编号设置视频和通道交换等。</span></td></tr><tr><td style='text-align:left;' ><span>devicevideosmart</span></td><td style='text-align:left;' ><span>人工智能处理类，最常见的应用就是设置一个视频控件，然后在视频控件上绘制人脸框、文字信息等，比如设备的实时运行状态。</span></td></tr></tbody></table></figure><h5 id='11325-模块-usercontrol'><span>11.3.2.5 模块-usercontrol</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>gaugecloud</span></td><td style='text-align:left;' ><span>云台仪表盘控件。</span></td></tr><tr><td style='text-align:left;' ><span>cityhelper</span></td><td style='text-align:left;' ><span>省市县联动类，通过从json文件读取省市县信息。</span></td></tr><tr><td style='text-align:left;' ><span>weather</span></td><td style='text-align:left;' ><span>城市天气类，最后显示在标题栏上，实时显示设置的城市的最近几天的天气。</span></td></tr><tr><td style='text-align:left;' ><span>widgetsound</span></td><td style='text-align:left;' ><span>声音面板控件，主界面右下角单击弹出音量条。</span></td></tr></tbody></table></figure><h4 id='1133-核心通用类库'><span>11.3.3 核心通用类库</span></h4><p><span> </span><img src="snap/11-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的全部是个人一直持续更新完善的独创的轮子，所有的项目都公用这些轮子，用到哪个就包含哪个进来，更新只需要更新轮子代码就行。</span></p><p><span>视频监控系统包含的轮子超级丰富给力，物超所值，涵盖了数据导出模块、数据库应用、音频播放和录制、视频播放和录制、ONVIF通信、TCP文件传输、地图应用、通用浏览器内核等。</span></p><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>core_audio</span></td><td style='text-align:left;' ><span>音频播放和录制，包括音频输入输出设备管理、音频播放、音频录制、音频振幅控件等。</span></td></tr><tr><td style='text-align:left;' ><span>core_common</span></td><td style='text-align:left;' ><span>通用函数，包括通用秘钥、通用导航、通用样式、声音播放、日志记录、运行时间记录等。</span></td></tr><tr><td style='text-align:left;' ><span>core_control</span></td><td style='text-align:left;' ><span>通用自定义控件，很多系统经常用到的控件全部放在这里，比如开关按钮、设备容器、设备按钮、颜色下拉框等。</span></td></tr><tr><td style='text-align:left;' ><span>core_dataout</span></td><td style='text-align:left;' ><span>数据导入导出到xls/pdf和打印类库，极速、跨平台、无依赖。</span></td></tr><tr><td style='text-align:left;' ><span>core_db</span></td><td style='text-align:left;' ><span>数据库通用类库比如数据库线程管理、数据清理、数据采集等。</span></td></tr><tr><td style='text-align:left;' ><span>core_form</span></td><td style='text-align:left;' ><span>通用的用户登录、用户退出、用户管理、数据库配置界面类等。</span></td></tr><tr><td style='text-align:left;' ><span>core_map</span></td><td style='text-align:left;' ><span>地图综合应用类库，百度地图（支持在线离线）和echart封装类等。</span></td></tr><tr><td style='text-align:left;' ><span>core_onvif</span></td><td style='text-align:left;' ><span>onvif功能封装类，包括设备搜索、云台控制、设备参数设置等。</span></td></tr><tr><td style='text-align:left;' ><span>core_qthelper</span></td><td style='text-align:left;' ><span>通用的辅助类，包括自定义对话框，全局辅助函数，图形字体等。</span></td></tr><tr><td style='text-align:left;' ><span>core_tcpfile</span></td><td style='text-align:left;' ><span>文件多线程收发类，支持多个并发。</span></td></tr><tr><td style='text-align:left;' ><span>core_video</span></td><td style='text-align:left;' ><span>视频播放核心类，包括了监控画面切换控件、视频回放控件、视频播放组件结构体、视频播放辅助函数、视频解码线程类、视频显示控件类等。</span></td></tr><tr><td style='text-align:left;' ><span>core_videobase</span></td><td style='text-align:left;' ><span>视频相关基类，包括音视频文件保存基类、视频解码基类、视频控件基类、视频悬浮工具栏、视频控件结构体等。</span></td></tr><tr><td style='text-align:left;' ><span>core_videoffmpeg</span></td><td style='text-align:left;' ><span>视频监控内核ffmpeg版本，本系统默认采用的内核。包括使用ffmpeg采集和保存到mp4文件的类。</span></td></tr><tr><td style='text-align:left;' ><span>core_videohelper</span></td><td style='text-align:left;' ><span>监控内核辅助类，包括本地视音频设备名称获取，滤镜字符串获取，地址获取辅助类等。</span></td></tr><tr><td style='text-align:left;' ><span>core_videoopengl</span></td><td style='text-align:left;' ><span>opengl封装类，支持打开yuv/nv12文件，绘制yuv/nv12帧数据，一般搭配ffmpeg视频内核显示视频，直接走GPU绘制。</span></td></tr><tr><td style='text-align:left;' ><span>core_webview</span></td><td style='text-align:left;' ><span>通用浏览器控件类，同时支持webkit、wenengine、miniblink三种内核，打通了所有的Qt版本。</span></td></tr></tbody></table></figure><h5 id='11331-模块-coreaudio'><span>11.3.3.1 模块-core_audio</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>audiohelper</span></td><td style='text-align:left;' ><span>音频相关辅助函数，比如获取音频输入输出设备、根据设备名称查找设备对象、初始化音频格式、获取对应音频格式最大振幅、获取对应音频格式音频数据的振幅级别等。</span></td></tr><tr><td style='text-align:left;' ><span>audiolevel</span></td><td style='text-align:left;' ><span>音频振幅控件，根据传入的音频振幅大小绘制振幅，可设置颜色。</span></td></tr><tr><td style='text-align:left;' ><span>audioplayer</span></td><td style='text-align:left;' ><span>音频播放类，可以设置声音大小和静音状态，支持带参数打开音频输入和输出设备，自动关联音频输入输出设备形成话筒和音响联动。</span></td></tr><tr><td style='text-align:left;' ><span>audiorecorder</span></td><td style='text-align:left;' ><span>音频录制类，可以设置音频录制的参数，包括采样大小、比特率、通道数、质量级别、编码模式等。</span></td></tr></tbody></table></figure><h5 id='11332-模块-corecommon'><span>11.3.3.2 模块-core_common</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>base64helper</span></td><td style='text-align:left;' ><span>图片及文字和base64编码之间转换的类。</span></td></tr><tr><td style='text-align:left;' ><span>commonkey</span></td><td style='text-align:left;' ><span>通用秘钥管理类，指定校验秘钥文件，可设置运行时间、设备数量等限制，支持根据硬件指纹特征生成机器码文件等。</span></td></tr><tr><td style='text-align:left;' ><span>commonnav</span></td><td style='text-align:left;' ><span>通用菜单导航管理类，用来控制和显示顶部导航栏、左侧导航栏的样式。很多子界面需要用到，所以封装成一个专门管理这个的类。</span></td></tr><tr><td style='text-align:left;' ><span>commonstyle</span></td><td style='text-align:left;' ><span>通用样式管理类，比如Qt自带类窗体样式、自定义控件样式、分页导航样式、导航按钮样式、开关按钮样式等。相当于将多个项目常用的自定义样式封装一起做成通用。</span></td></tr><tr><td style='text-align:left;' ><span>framelesswidget2</span></td><td style='text-align:left;' ><span>无边框窗体拉伸类，边框四周八个方位都可以自由拉伸，可设置是否允许拖动和拉伸。</span></td></tr><tr><td style='text-align:left;' ><span>playwav</span></td><td style='text-align:left;' ><span>声音文件播放类，通用Qt456，自动识别当前Qt版本使用对应的类，Qt4采用QSound，Qt5以上采用QSoundEffect，嵌入式采用对应的命令行aplay、mpv来播放。</span></td></tr><tr><td style='text-align:left;' ><span>savelog</span></td><td style='text-align:left;' ><span>日志钩子类，将系统中所有的打印信息转为日志存储或者输出到网络等，可以开启用来打印输出日志信息。</span></td></tr><tr><td style='text-align:left;' ><span>saveruntime</span></td><td style='text-align:left;' ><span>保存运行时间类，用来存储系统启动后每隔一段时间就输出一条记录用来记录启动后软件运行了多久，方便分析问题。</span></td></tr></tbody></table></figure><h5 id='11333-模块-corecontrol'><span>11.3.3.3 模块-core_control</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>bottomwidget</span></td><td style='text-align:left;' ><span>通用底部状态栏控件，可以设置软件名称、版本号、运行时间等。</span></td></tr><tr><td style='text-align:left;' ><span>colorcombobox</span></td><td style='text-align:left;' ><span>颜色下拉框控件，在系统设置中有。</span></td></tr><tr><td style='text-align:left;' ><span>cpumemorylabel</span></td><td style='text-align:left;' ><span>CPU和内存使用情况标签控件，主界面右上角显示。</span></td></tr><tr><td style='text-align:left;' ><span>customtitlebar</span></td><td style='text-align:left;' ><span>停靠窗体自定义标题栏控件。</span></td></tr><tr><td style='text-align:left;' ><span>devicebutton</span></td><td style='text-align:left;' ><span>设备按钮控件，比如图片地图模块中用到，可设置不同的图标样式和状态等，双击发出信号进行相应处理比如弹出对应窗体等。</span></td></tr><tr><td style='text-align:left;' ><span>lcddatetime</span></td><td style='text-align:left;' ><span>软件右上角显示时间的控件。</span></td></tr><tr><td style='text-align:left;' ><span>panelwidget</span></td><td style='text-align:left;' ><span>面板容器控件，主界面子模块表格消息，就用到此控件，用于将一堆widget放到此容器进行管理，自动形成滚动条等。</span></td></tr><tr><td style='text-align:left;' ><span>switchbutton</span></td><td style='text-align:left;' ><span>开关按钮控件，在系统设置中存在大量该控件。</span></td></tr><tr><td style='text-align:left;' ><span>xslider</span></td><td style='text-align:left;' ><span>滑动条控件，在原有滑动条基础上增加了鼠标按下立即定位等。</span></td></tr></tbody></table></figure><h5 id='11334-模块-coredataout'><span>11.3.3.4 模块-core_dataout</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>datacreat</span></td><td style='text-align:left;' ><span>通用数据报表内容创建类，比如生成表格格式的html内容，然后赋值给dataprint直接打印，里面举例了图文混排的报告内容，后期会不断增加其他模板，也可以自行增加其他模板数据。</span></td></tr><tr><td style='text-align:left;' ><span>datacsv</span></td><td style='text-align:left;' ><span>导入导出数据，csv格式，可设置分隔符。拓展名。过滤条件等。</span></td></tr><tr><td style='text-align:left;' ><span>datahead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>datahelper</span></td><td style='text-align:left;' ><span>辅助类，比如校验规则函数，通用数据导出+打印函数。</span></td></tr><tr><td style='text-align:left;' ><span>dataprint</span></td><td style='text-align:left;' ><span>数据打印到pdf及纸张，支持多线程。</span></td></tr><tr><td style='text-align:left;' ><span>dataxls</span></td><td style='text-align:left;' ><span>数据导出到xls类，支持多线程导出。</span></td></tr></tbody></table></figure><h5 id='11335-模块-coredb'><span>11.3.3.5 模块-core_db</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>dbcleanthread</span></td><td style='text-align:left;' ><span>自动清理数据线程类。</span></td></tr><tr><td style='text-align:left;' ><span>dbconnthread</span></td><td style='text-align:left;' ><span>数据库通信管理线程类。</span></td></tr><tr><td style='text-align:left;' ><span>dbdelegate</span></td><td style='text-align:left;' ><span>自定义委托全家桶，包括复选框、下拉框、密码框、按钮等。</span></td></tr><tr><td style='text-align:left;' ><span>dbhead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>dbhelper</span></td><td style='text-align:left;' ><span>各种数据库应用函数封装，比如初始化数据库、执行sql语句等。</span></td></tr><tr><td style='text-align:left;' ><span>dbhttpthread</span></td><td style='text-align:left;' ><span>网络请求数据采集类。</span></td></tr><tr><td style='text-align:left;' ><span>dbpage</span></td><td style='text-align:left;' ><span>数据库通用翻页类。</span></td></tr><tr><td style='text-align:left;' ><span>dbpagemodel</span></td><td style='text-align:left;' ><span>数据库翻页类数据模型。</span></td></tr><tr><td style='text-align:left;' ><span>navpage</span></td><td style='text-align:left;' ><span>分页导航控件。</span></td></tr></tbody></table></figure><h5 id='11336-模块-coreform'><span>11.3.3.6 模块-core_form</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>formhelper</span></td><td style='text-align:left;' ><span>封装的导入导出、导出数据到xls/pdf和打印数据、自动备份数据、保存最后打开的文件夹等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigdb</span></td><td style='text-align:left;' ><span>通用数据库管理界面类，可选不同的数据库类型，填入用户信息，执行检测连接和初始化数据操作。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfiguser</span></td><td style='text-align:left;' ><span>通用用户管理界面类，可添加、删除、修改用户信息，包括权限分配等，可导入导出打印用户信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmlogin</span></td><td style='text-align:left;' ><span>通用用户登录界面类，包括自动登录和记住密码复选框，多次密码错误校验，记住当前用户信息等。三次错误关闭，下拉可选用户，内置超级密码。</span></td></tr><tr><td style='text-align:left;' ><span>frmlogout</span></td><td style='text-align:left;' ><span>通用用户退出界面类，三次错误关闭，下拉可选用户，内置超级密码。</span></td></tr><tr><td style='text-align:left;' ><span>userhelper</span></td><td style='text-align:left;' ><span>通用用户权限管理类，内置7种类型权限，对应权限名称可自定义，一般在用户切换对应界面或者单击了对应功能按钮的时候触发。</span></td></tr></tbody></table></figure><h5 id='11337-模块-coremap'><span>11.3.3.7 模块-core_map</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>echartjs</span></td><td style='text-align:left;' ><span>echart模块中用到的json文件转js文件，获取js文件中的名字和经纬度等处理。</span></td></tr><tr><td style='text-align:left;' ><span>echarts</span></td><td style='text-align:left;' ><span>echart封装类，可加载仪表盘、闪烁点图、迁徙图、世界地图、区域地图等，每个点可自定义颜色和提示信息等。</span></td></tr><tr><td style='text-align:left;' ><span>mapbaidu</span></td><td style='text-align:left;' ><span>百度地图封装类，支持在线和离线两种模式。</span></td></tr></tbody></table></figure><h5 id='11338-模块-coreonvif'><span>11.3.3.8 模块-core_onvif</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>onvifbase</span></td><td style='text-align:left;' ><span>基础类，用于获取设备信息、服务文件地址、能力文件地址、媒体文件地址、视频流地址等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifdevice</span></td><td style='text-align:left;' ><span>设备类，核心处理及管理，包括设置用户信息请求onvif地址、获取设备信息、云台控制、事件订阅、抓拍图片等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifevent</span></td><td style='text-align:left;' ><span>事件订阅具体实现类，可设置请求超时时间等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifhead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>onvifhelper</span></td><td style='text-align:left;' ><span>辅助类，比如获取UUID用于请求、判断IP合法、获取本机IP地址集合、管理系统中所有onvif设备对象等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifmedia</span></td><td style='text-align:left;' ><span>获取媒体文件具体解析类。</span></td></tr><tr><td style='text-align:left;' ><span>onvifother</span></td><td style='text-align:left;' ><span>其他处理类，比如系统重启、NTP校时、获取和设置网络信息、获取和设备时间、获取和设置图片参数等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifptz</span></td><td style='text-align:left;' ><span>云台控制实现类，包括绝对移动、相对移动等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifquery</span></td><td style='text-align:left;' ><span>数据查询类，用于将接收到的xml数据解析，并赋值字符串比如命名空间、设备地址、媒体地址、事件地址等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifrequest</span></td><td style='text-align:left;' ><span>网络请求类，包括设置用户信息、获取用户token数据、获取xml头部数据等，通用的请求数据返回结果函数。</span></td></tr><tr><td style='text-align:left;' ><span>onvifsearch</span></td><td style='text-align:left;' ><span>设备搜索类，支持广播搜索、指定地址搜索，可获取设备信息集合、获取设备地址集合。</span></td></tr><tr><td style='text-align:left;' ><span>onvifservices</span></td><td style='text-align:left;' ><span>服务类，用于获取媒体地址、云台地址等。</span></td></tr><tr><td style='text-align:left;' ><span>onvifsnap</span></td><td style='text-align:left;' ><span>图片抓拍实现类，包括获取抓图地址、抓拍图片等。</span></td></tr></tbody></table></figure><h5 id='11339-模块-coreqthelper'><span>11.3.3.9 模块-core_qthelper</span></h5><p><span>本组件涵盖的功能较多，所以采用了分层管理代码结构。</span></p><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>iconhelper</span></td><td style='text-align:left;' ><span>万能图形字体类，可传入多种图形字体文件，一个类通用所有图形字体。</span></td></tr><tr><td style='text-align:left;' ><span>globalconfig</span></td><td style='text-align:left;' ><span>存储当前组件的配置参数信息，比如全局的字体名称、字号、无边框窗体的最小化最大化关闭等图标、样式表的颜色值。</span></td></tr><tr><td style='text-align:left;' ><span>globalhead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>globalstyle</span></td><td style='text-align:left;' ><span>当前组件通用样式设置管理类，可以指定枚举类型样式、传入样式内容设置、获取样式表文件对应的颜色值等。当前组件样式相关的处理函数都放在这里，统一管理。</span></td></tr></tbody></table></figure><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>qtabout</span></td><td style='text-align:left;' ><span>关于系统对话框，可传入软件标题、版本、版权、网址等信息。</span></td></tr><tr><td style='text-align:left;' ><span>qtdateselect</span></td><td style='text-align:left;' ><span>自定义日期范围选择对话框。</span></td></tr><tr><td style='text-align:left;' ><span>qtinputbox</span></td><td style='text-align:left;' ><span>自定义输入框窗体，可指定不同的输入类型比如文本框、下拉框等。</span></td></tr><tr><td style='text-align:left;' ><span>qtmessagebox</span></td><td style='text-align:left;' ><span>自定义信息消息框窗体，可设置关闭倒计时，不同的类型比如信息框、询问框、错误框等。</span></td></tr><tr><td style='text-align:left;' ><span>qtsplash</span></td><td style='text-align:left;' ><span>自定义弹出提示信息，提示完自动消息关闭。</span></td></tr><tr><td style='text-align:left;' ><span>qttipbox</span></td><td style='text-align:left;' ><span>自定义右下角信息对话框，可设置对齐方式、关闭倒计时等。</span></td></tr><tr><td style='text-align:left;' ><span>qtform</span></td><td style='text-align:left;' ><span>自定义无边框窗体，可设置标题，各种图标等。</span></td></tr></tbody></table></figure><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>qthelper</span></td><td style='text-align:left;' ><span>项目通用辅助类，各种常用函数的封装，比如获取当前屏幕分辨率、设置字体、设置编码、加载翻译文件、各种进制数据转换、弹出各种对话框、设置延时时间等。</span></td></tr><tr><td style='text-align:left;' ><span>qthelpercore</span></td><td style='text-align:left;' ><span>获取当前桌面分辨率，设置编码、字体、翻译文件等。</span></td></tr><tr><td style='text-align:left;' ><span>qthelperdata</span></td><td style='text-align:left;' ><span>16进制、2进制、10进制互相转换，16进制字符串、字节数组互相转换，字节数组转int和short，CRC校验等。</span></td></tr><tr><td style='text-align:left;' ><span>qthelperfile</span></td><td style='text-align:left;' ><span>选择文件、保存文件、选择目录等对话框，复制文件、删除文件等。</span></td></tr><tr><td style='text-align:left;' ><span>qthelperform</span></td><td style='text-align:left;' ><span>设置无边框窗体、边框阴影，弹出信息框、错误框、询问框、日期选择框、关于对话框、中间提示框等。</span></td></tr><tr><td style='text-align:left;' ><span>qthelperimage</span></td><td style='text-align:left;' ><span>获取等比例缩放图片，通用设置logo图片，支持资源文件、本地图片、图形字体、svg自动变色等多种形式。</span></td></tr><tr><td style='text-align:left;' ><span>qthelpernet</span></td><td style='text-align:left;' ><span>获取本机IP地址集合，获取外网IP地址，判断IP、MAC等是否合法，下载网络文件，IP地址字符串与整型互相转换。</span></td></tr><tr><td style='text-align:left;' ><span>qthelperother</span></td><td style='text-align:left;' ><span>初始化数据库文件，设置系统时间、开机启动，设置图标到按钮，写入临时消息的文本文件等。</span></td></tr></tbody></table></figure><h5 id='113310-模块-coretcpfile'><span>11.3.3.10 模块-core_tcpfile</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>tcpfilehead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>tcpfilehelper</span></td><td style='text-align:left;' ><span>辅助类，包括将字节转为MB单位、初始化表格控件、生成表格行、数据加密解密、解压文件、重启系统等。</span></td></tr><tr><td style='text-align:left;' ><span>tcpreceivefileserver</span></td><td style='text-align:left;' ><span>接收文件服务类，管理多个接收文件线程，支持监听端口被动接收文件和主动连接服务器接收文件。</span></td></tr><tr><td style='text-align:left;' ><span>tcpreceivefilethread</span></td><td style='text-align:left;' ><span>接收文件线程类，根据发送的文件名、包编号、块大小、挨个接收数据最终形成文件，可设置保存文件夹等。</span></td></tr><tr><td style='text-align:left;' ><span>tcpsearchfileserver</span></td><td style='text-align:left;' ><span>搜索文件服务类，目前没用，用于接收请求搜索文件是否存在。</span></td></tr><tr><td style='text-align:left;' ><span>tcpsendfilethread</span></td><td style='text-align:left;' ><span>发送文件线程类，按照 文件开始符+文件大小+文件内容+文件结束符 逐个分包发送，可对文件的每个包进行加密传输。</span></td></tr></tbody></table></figure><h5 id='113311-模块-corevideo'><span>11.3.3.11 模块-core_video</span></h5><p><span>视频组件继承和依赖关系说明：</span></p><ol start='' ><li><p><span>videobase是基类组件，video是视频播放组件，依赖基类组件，videoffmpeg是具体的内核实现组件，依赖视频播放组件。</span></p></li><li><p><span>video组件中的videothread解码线程类继承自videobase基类组件中的abstractvideothread。</span></p></li><li><p><span>video组件中的videowidgetx视频显示类继承自videobase基类组件中的abstractvideowidget。</span></p></li><li><p><span>videoffmpeg组件中的ffmpegthread继承自video组件中的videothread。</span></p></li><li><p><span>videoffmpeg组件中的ffmpegsave继承自videobase组件中的abstractsavethread。</span></p></li><li><p><span>按照此规则还有其他内核比如vlc组件中的vlcthread也是继承自videothread，mpv组件中的mpvthread也是继承自videothread。这样新增一种内核只要具体实现部分处理函数即可应用整个视频框架。</span></p></li><li><p><span>通过多层基类继承关系，使得动态挂载任意解码内核极为方便。</span></p></li><li><p><span>为何在video视频组件的基础上还要提炼一个videobase基类组件？因为该基类组件还可以提供给camera本地摄像头采集组件使用，基类中的变量、函数、处理逻辑几乎一致，但是又有特殊性，所以需要分开再提炼出videobase基类。</span></p></li></ol><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>videobox</span></td><td style='text-align:left;' ><span>监控画面切换控件，将所有通道切换处理全部集中到一个类，通用异形布局切换函数，可以参考进行自定义异形布局，通道布局切换发出信号通知，支持自定义子菜单布局内容。</span></td></tr><tr><td style='text-align:left;' ><span>videohelper</span></td><td style='text-align:left;' ><span>视频相关辅助函数，比如根据url地址取出ip地址、校验网络地址是否可达、检查地址是否正常、根据地址获取本地摄像头参数、获取本地桌面采集参数、创建视频采集类、对采集线程设置参数等。</span></td></tr><tr><td style='text-align:left;' ><span>videomanage</span></td><td style='text-align:left;' ><span>视频线程管理类，全局单例，将所有视频控件发给此类管理，负责挨个打开视频、应用录像计划等。</span></td></tr><tr><td style='text-align:left;' ><span>videoplayback</span></td><td style='text-align:left;' ><span>视频回放控件，支持多个通道，显示每个通道对应的视频段。</span></td></tr><tr><td style='text-align:left;' ><span>videostruct</span></td><td style='text-align:left;' ><span>视频播放组件结构体定义类，包括解析内核枚举值、视频类型枚举值、解码策略枚举值、视频采集参数结构体。</span></td></tr><tr><td style='text-align:left;' ><span>videotask</span></td><td style='text-align:left;' ><span>视频任务线程类，全局单例，可以随时插入一些视频相关的任务进行处理，比如vlc录制视频后需要重命名文件，mpv内核关闭视频后鼠标指针打圈圈需要复位。</span></td></tr><tr><td style='text-align:left;' ><span>videothread</span></td><td style='text-align:left;' ><span>视频解码线程类，内置了共享解码线程处理逻辑，可以打开视频、关闭视频、设置视频宽高比例、获取文件总时长、获取媒体信息、获取和设置播放位置、获取和设置播放速度、获取和设置音量大小、获取和设置静音状态等。</span></td></tr><tr><td style='text-align:left;' ><span>videoutil</span></td><td style='text-align:left;' ><span>视频相关辅助函数，加载视频内核、视频地址、视频模式、解码策略、编码策略、硬件加速、通信协议、缓存时间、读取超时等。</span></td></tr><tr><td style='text-align:left;' ><span>videowidgetx</span></td><td style='text-align:left;' ><span>视频播放控件，一个控件对应一个解码线程，提供播放成功、播放结束、收到截图、工具栏按钮单击等处理，提供开始播放、停止播放、暂停播放、继续播放、抓拍截图、开始录制、暂停录制、停止录制等接口。</span></td></tr></tbody></table></figure><h5 id='113312-模块-corevideobase'><span>11.3.3.12 模块-core_videobase</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>abstractsavethread</span></td><td style='text-align:left;' ><span>音视频存储基类，可以设置需要保存的音视频文件类型，比如音频文件类型有pcm、wav、aac，视频文件类型有yuv、h264、mp4，提供开始保存、暂停保存、停止保存等接口。</span></td></tr><tr><td style='text-align:left;' ><span>abstractvideosurface</span></td><td style='text-align:left;' ><span>视频回调基类，用于Qt中的QCamera和QMedia类播放后拿到回调视频数据，这样可以取到一张张图片。</span></td></tr><tr><td style='text-align:left;' ><span>abstractvideothread</span></td><td style='text-align:left;' ><span>视频解码线程基类，摄像头采集线程和视频采集线程都继承自此类，将各种公用的变量、函数、接口、信号槽全部放在基类，包括了停止线程标志位、打开是否成功标志位、暂停采集标志位、开始截图标志位、正在录制标志位，提供了虚函数开始播放、停止播放、暂停播放、继续播放、抓拍截图、截图完成、开始录制、暂停录制、停止录制等，提供写入视频数据到文件、写入音频数据到文件槽函数。</span></td></tr><tr><td style='text-align:left;' ><span>abstractvideowidget</span></td><td style='text-align:left;' ><span>视频显示控件基类，</span></td></tr><tr><td style='text-align:left;' ><span>bannerwidget</span></td><td style='text-align:left;' ><span>悬浮工具栏控件，可以设置各种颜色、按钮图标集合、按钮名称集合、按钮提示信息集合等，悬浮条位置支持上下左右四个方位。</span></td></tr><tr><td style='text-align:left;' ><span>widgethelper</span></td><td style='text-align:left;' ><span>窗体相关辅助函数，包括传入图片尺寸和窗体区域及边框大小返回居中区域(scaleMode: 0-自动调整 1-等比缩放 2-拉伸填充)、绘制矩形区域比如人脸框、绘制点集合多边形路径比如三角形、绘制路径集合、显示截图预览等。</span></td></tr></tbody></table></figure><h5 id='113313-模块-corevideoffmpeg'><span>11.3.3.13 模块-core_videoffmpeg</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>ffmpegfilter</span></td><td style='text-align:left;' ><span>滤镜相关静态函数，传入滤镜结构体数据获取滤镜字符串，初始化滤镜、释放滤镜数据。在ffmpegthread中调用。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpeghelper</span></td><td style='text-align:left;' ><span>相关辅助函数，包括初始化各种参数、格式枚举值转字符串、初始化音频转换上下文、初始化和获取音频通道相关、获取和设置旋转角度、获取解码器枚举值和名称、获取码率格式媒体类型、获取分辨率采样率流信息、拷贝上下文参数、释放数据帧数据包等。其中为了兼容ffmpeg2-ffmpeg6以及后续所有版本，在这里全部做了不同版本对应不同函数调用的区分。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegsave</span></td><td style='text-align:left;' ><span>视频存储类，用于保存h264和mp4文件，同时也可用于推流。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegsavehelper</span></td><td style='text-align:left;' ><span>视频存储辅助类，包括校验是否需要启用编码、获取保存的格式、根据分辨率获取码率、根据缩放字符串获取最终宽高、初始化视频编码器、初始化视频编码器上下文、初始化视频转换相关、初始化音频编码器上下文、初始化音频转换相关、封装格式(写入sps/pps信息)、通用软编码(支持音频视频)、转换时间基准等。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegsync</span></td><td style='text-align:left;' ><span>音视频同步线程类，解码后的音视频数据发给本类进行时间同步处理，采用的外部时钟同步策略。音视频播放的进度也在本类中。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegthread</span></td><td style='text-align:left;' ><span>视频解码线程核心，从打开地址、分配解码器、初始化参数、取出音视频数据解码、关闭并释放资源等都在本类实现。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegthreadhelper</span></td><td style='text-align:left;' ><span>视频解码辅助类，包括根据解码策略获取解码参数、校验硬解码、读取封面、初始化视频解码器、初始化硬解相关、初始化解码视频相关数据、初始化解码音频相关数据、计算实时码率、通用硬解码(音频没有硬解码)、通用软解码(支持音频视频)、打开超时和读取超时回调等。</span></td></tr><tr><td style='text-align:left;' ><span>ffmpegutil</span></td><td style='text-align:left;' ><span>其他辅助函数，比如打印输出编码解码信息、打印编码器的相关参数、打印设备列表和参数、获取输入输出设备名称集合、视频帧旋转、获取指定文件时长、解析sps/pps数据等。</span></td></tr></tbody></table></figure><h5 id='113314-模块-corevideohelper'><span>11.3.3.14 模块-core_videohelper</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>audioplayer</span></td><td style='text-align:left;' ><span>音频播放类，空的，纯粹为了在没有Qt音频播放类QAudioOutput的时候使用，有些Qt版本或者嵌入式板子环境未必有这个类，但是又不能影响整个组件的运行，于是定义了空的类，函数正常调用但是不做任何处理。</span></td></tr><tr><td style='text-align:left;' ><span>deviceinfohelper</span></td><td style='text-align:left;' ><span>获取本地视音频输入设备名称，通用函数取出本地设备带分辨率和帧率等信息，根据屏幕区域校验参数，获取本地屏幕信息和当前屏幕区域。</span></td></tr><tr><td style='text-align:left;' ><span>filterhelper</span></td><td style='text-align:left;' ><span>滤镜相关辅助类，传入旋转角度获取旋转滤镜字符串、根据标签信息获取对应滤镜字符串、根据图形信息获取对应滤镜字符串、转换滤镜字符串到ffmpeg格式、传入标签队列和图形队列获取滤镜字符串。此类主要给ffmpeg内核、qtav内核、mdk内核使用。</span></td></tr><tr><td style='text-align:left;' ><span>imagelabel</span></td><td style='text-align:left;' ><span>图片标签控件，多线程绘制传入的图片，性能比setpixmap更优。</span></td></tr><tr><td style='text-align:left;' ><span>urlhelper</span></td><td style='text-align:left;' ><span>通用地址辅助类，设备厂家类型结构体、地址参数结构体，各个厂家的实时及回放视频流字符串函数，根据url播放地址获取地址对应的各种信息比如IP地址和端口等。</span></td></tr><tr><td style='text-align:left;' ><span>urlutil</span></td><td style='text-align:left;' ><span>视频地址相关静态函数，可以读取和写入地址到文本文件，用作历史记录，内置了各种类型（rtsp、http、音频文件、视频文件、网络文件、本地摄像头）的测试音视频地址集合。</span></td></tr></tbody></table></figure><h5 id='113315-模块-corevideoopengl'><span>11.3.3.15 模块-core_videoopengl</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>openglinclude</span></td><td style='text-align:left;' ><span>当前组件头文件。</span></td></tr><tr><td style='text-align:left;' ><span>nv12glwidget</span></td><td style='text-align:left;' ><span>空类，用于没有opengl的Qt版本中保证程序能够继续运行。</span></td></tr><tr><td style='text-align:left;' ><span>nv12openglwidget</span></td><td style='text-align:left;' ><span>继承自QOpenGLWidget的NV12格式OPENGL绘制窗体。</span></td></tr><tr><td style='text-align:left;' ><span>yuvglwidget</span></td><td style='text-align:left;' ><span>空类，用于没有opengl的Qt版本中保证程序能够继续运行。</span></td></tr><tr><td style='text-align:left;' ><span>yuvopenglwidget</span></td><td style='text-align:left;' ><span>继承自QOpenGLWidget的YUV格式OPENGL绘制窗体。</span></td></tr></tbody></table></figure><h5 id='113316-模块-corewebview'><span>11.3.3.16 模块-core_webview</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>webcore.pri</span></td><td style='text-align:left;' ><span>通用的根据不同的Qt版本、不同的编译器环境、不同的操作系统，加载对应的浏览器内核模块和定义不同的变量。</span></td></tr><tr><td style='text-align:left;' ><span>miniblink</span></td><td style='text-align:left;' ><span>miniblink封装处理类。</span></td></tr><tr><td style='text-align:left;' ><span>webhelper</span></td><td style='text-align:left;' ><span>经纬度转换、获取小数点经纬度值等常用处理函数。</span></td></tr><tr><td style='text-align:left;' ><span>webjsdata</span></td><td style='text-align:left;' ><span>通用的浏览器控件和Qt程序交互数据中转类。</span></td></tr><tr><td style='text-align:left;' ><span>webview</span></td><td style='text-align:left;' ><span>通用浏览器控件，支持webkit、webengine、miniblink。</span></td></tr></tbody></table></figure><h4 id='1134-界面ui'><span>11.3.4 界面UI</span></h4><p><span> </span><img src="snap/11-3-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>界面说明</span></strong></p><ol start='' ><li><p><span>这里分门别类存放的各种功能集合的界面类。</span></p></li><li><p><span>每个类都一个ui文件、一个h头文件、一个cpp实现文件。</span></p></li><li><p><span>可以方便快速查找对应功能的界面，也方便拓展增加界面。</span></p></li><li><p><span>不仅分文件夹存放的，而且命名也尽量按照对应功能打头，比如系统设置模块中的都用frmconfig打头。</span></p></li><li><p><span>外层文件夹是整齐的，内部代码也是整齐的。</span></p></li></ol><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmconfig</span></td><td style='text-align:left;' ><span>系统设置模块，包括基本设置、录像机管理、摄像机管理、轮询管理、用户管理、视频上传等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdata</span></td><td style='text-align:left;' ><span>日志查询模块，包括本地日志、设备日志等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemo</span></td><td style='text-align:left;' ><span>演示demo示例，用于演示具体控件或者功能的使用，方便学习参考，比如视频图片、视频控件、视频存储都单独的使用demo。</span></td></tr><tr><td style='text-align:left;' ><span>frmipc</span></td><td style='text-align:left;' ><span>存放摄像机处理相关的模块，比如设备控制，云台控制、预置位、巡航设置等。之前放在frmmodule模块中，后面独立出来管理更方便。</span></td></tr><tr><td style='text-align:left;' ><span>frmmain</span></td><td style='text-align:left;' ><span>主界面模块，包括登录登出界面、主界面、右上角时间组件、欢迎组件等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmap</span></td><td style='text-align:left;' ><span>地图模块，包括通用地图内核界面、图片地图、在线地图、离线地图、路径规划等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmodule</span></td><td style='text-align:left;' ><span>停靠子窗体模块，包括停靠窗体管理核心类、设备列表、窗口信息、图文警情、设备轨迹、网页浏览等模块。将摄像机、机器人、无人机相关的模块放到了对应的模块文件夹，这里放的是系统通用的模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmrobot</span></td><td style='text-align:left;' ><span>无人机模块，包括图像增强、飞行监控等模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmuavs</span></td><td style='text-align:left;' ><span>无人机模块，包括图像增强、飞行监控等模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideo</span></td><td style='text-align:left;' ><span>视频监控模块，所有视频监控相关的都放在这里，包括主界面的视频监控布局窗体、视频回放、远程回放、图片回放等。</span></td></tr></tbody></table></figure><h5 id='11341-模块-frmconfig'><span>11.3.4.1 模块-frmconfig</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmconfig</span></td><td style='text-align:left;' ><span>系统设置模块主界面，采用堆栈窗体形式，加载多个子界面比如摄像机管理、轮询管理等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigipc</span></td><td style='text-align:left;' ><span>摄像机管理，可以增加、删除、修改、清空、导入、导出、打印摄像机信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigipcsearch</span></td><td style='text-align:left;' ><span>onvif设备搜索，独立出来的窗体，可以搜索局域网内的所有onvif摄像机信息，搜索完以后获取摄像机的视频流地址等，最后可以单个添加或者批量选中添加到摄像机信息表格中。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfignvr</span></td><td style='text-align:left;' ><span>录像机管理，可以增加、删除、修改、清空、导入、导出、打印录像机信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigpoll</span></td><td style='text-align:left;' ><span>轮询管理，可以增加、删除、修改、清空、导入、导出、打印轮询点信息。可以按照设定规则批量生成轮询点信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigpollplus</span></td><td style='text-align:left;' ><span>将轮询管理中的轮询参数配置、分组管理、批量添加等独立出来的界面，方便管理和拓展。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigsave</span></td><td style='text-align:left;' ><span>录像计划，可以对每个通道每周每天每半小时时间段设置是否存储录像。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigsystem</span></td><td style='text-align:left;' ><span>系统设置，包括基本设置、视频参数、数据库设置、地图配置、功能激活、颜色配置、串口配置、网络配置等。</span></td></tr></tbody></table></figure><h5 id='11342-模块-frmdata'><span>11.3.4.2 模块-frmdata</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmdata</span></td><td style='text-align:left;' ><span>日志查询模块主界面，采用堆栈窗体形式，加载多个子界面包括本地日志、设备日志等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdatadevice</span></td><td style='text-align:left;' ><span>设备日志，通过私有协议从NVR取对应设备日志信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmdatauser</span></td><td style='text-align:left;' ><span>本地地址，用户操作的日志信息，可查询和导出打印数据记录。</span></td></tr></tbody></table></figure><h5 id='11343-模块-frmdemo'><span>11.3.4.3 模块-frmdemo</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmdemo</span></td><td style='text-align:left;' ><span>单独的功能演示示例主窗体，加载多个子界面比如视频控件等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemohelper</span></td><td style='text-align:left;' ><span>通用辅助示例，主要演示qthelper通用组件中封装的函数如何使用，比如各种消息框、提示框等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideochange</span></td><td style='text-align:left;' ><span>通道交换示例，演示两个视频通道如何无缝切换。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideodrag</span></td><td style='text-align:left;' ><span>拖曳播放示例，演示从文件夹拖曳文件到视频控件播放。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideodraw</span></td><td style='text-align:left;' ><span>标签绘制示例，演示各种OSD标签示例和各种图形绘制示例。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideoimage</span></td><td style='text-align:left;' ><span>视频图片示例，从图片文件夹读取图片集合，定时器绘制取出图片发给视频控件绘制。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideoosd</span></td><td style='text-align:left;' ><span>动态标签示例，演示动态更新和插入OSD标签。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideoplay4</span></td><td style='text-align:left;' ><span>同步播放示例，演示4个通道切换进度条同步播放进度。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideoplus</span></td><td style='text-align:left;' ><span>视频叠加示例，多个视频控件叠加在一起同时播放，可以设置在四个角落位置。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideosave</span></td><td style='text-align:left;' ><span>视频保存示例，演示如何对视频控件进行视频保存，可动态保存。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideovolume</span></td><td style='text-align:left;' ><span>音频振幅示例，演示实时显示当前播放的音量大小音频振幅，柱状条显示。</span></td></tr><tr><td style='text-align:left;' ><span>frmdemovideowidget</span></td><td style='text-align:left;' ><span>视频控件示例，演示视频控件如何使用。</span></td></tr></tbody></table></figure><h5 id='11344-模块-frmipc'><span>11.3.4.4 模块-frmipc</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmipccontrol</span></td><td style='text-align:left;' ><span>设备控制模块，可对选中设备进行图片参数调节、NTP校时、设备重启、抓拍图片（ONVIF抓图）等。</span></td></tr><tr><td style='text-align:left;' ><span>frmipcnavigate</span></td><td style='text-align:left;' ><span>巡航管理模块，暂未实现，后期完善。</span></td></tr><tr><td style='text-align:left;' ><span>frmipcreset</span></td><td style='text-align:left;' ><span>预置位管理模块，暂未实现，后期完善。</span></td></tr><tr><td style='text-align:left;' ><span>frmipcptz</span></td><td style='text-align:left;' ><span>云台控制模块，可对选中的摄像机进行云台控制。</span></td></tr></tbody></table></figure><h5 id='11345-模块-frmmain'><span>11.3.4.5 模块-frmmain</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmmain</span></td><td style='text-align:left;' ><span>系统主界面，采用堆栈窗体，加载各个子模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmmain1</span></td><td style='text-align:left;' ><span>备用模块1界面，根据参数设置决定是否启用。</span></td></tr><tr><td style='text-align:left;' ><span>frmtimecpu</span></td><td style='text-align:left;' ><span>右上角日期时间+CPU内存显示。</span></td></tr><tr><td style='text-align:left;' ><span>frmwelcome</span></td><td style='text-align:left;' ><span>右上角欢迎信息界面。</span></td></tr></tbody></table></figure><h5 id='11346-模块-frmmap'><span>11.3.4.6 模块-frmmap</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmmap</span></td><td style='text-align:left;' ><span>地图管理主界面，采用堆栈窗体形式，加载各个子界面比如图片地图、在线地图、离线地图、路径规划等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmapcore</span></td><td style='text-align:left;' ><span>通用百度地图内核界面，用来加载百度地图，可设置在线、离线模式，有很多个窗体用到类似功能特意封装到一个类，重复利用，比如悬浮地图、飞行轨迹、路径规划等模块都用到了此内核。</span></td></tr><tr><td style='text-align:left;' ><span>frmmapdevice</span></td><td style='text-align:left;' ><span>通用的设备地图界面，在线地图和离线地图界面公用这个界面，唯一区别就是设置下地图的模式是在线还是离线。</span></td></tr><tr><td style='text-align:left;' ><span>frmmapimage</span></td><td style='text-align:left;' ><span>图片地图界面，设备作为一个个按钮点显示在对应地图上，可以拖动，双击弹出预览实时视频。</span></td></tr><tr><td style='text-align:left;' ><span>frmmaplocal</span></td><td style='text-align:left;' ><span>离线地图界面，可更新经纬度值、模拟运动轨迹等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmapweb</span></td><td style='text-align:left;' ><span>在线地图界面，可更新经纬度值、模拟运动轨迹等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmaproute</span></td><td style='text-align:left;' ><span>路径规划界面，可查询路线得到路线的经纬度坐标集合。</span></td></tr></tbody></table></figure><h5 id='11347-模块-frmmodule'><span>11.3.4.7 模块-frmmodule</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmdevicegps</span></td><td style='text-align:left;' ><span>设备轨迹模块，对设定的设备随机模拟轨迹，也可传入经纬度坐标值自动移动并绘制轨迹线条，不同设备可以不同颜色。</span></td></tr><tr><td style='text-align:left;' ><span>frmdevicetree</span></td><td style='text-align:left;' ><span>设备列表模块，读取设备信息加载形成树状列表，双击或者拖动到视频监控窗体直接播放视频，提供右键菜单作为演示如何使用。</span></td></tr><tr><td style='text-align:left;' ><span>frmmodule</span></td><td style='text-align:left;' ><span>主界面中心部分窗体，采用QMainWindow类，中间加载的视频监控面板，其余new出来每个子模块，子模块可停靠和悬浮拖动等。不同工作模式下的各种子模块都在此加载。同时负责管理模块的显示隐藏菜单。</span></td></tr><tr><td style='text-align:left;' ><span>frmmsglist</span></td><td style='text-align:left;' ><span>图文警情模块，也叫消息列表模块，带有右键菜单添加、删除、清空列表中的消息，双击可以弹出大图预览。</span></td></tr><tr><td style='text-align:left;' ><span>frmmsglistitem</span></td><td style='text-align:left;' ><span>图文警情模块子类，都是由一个个item组成放到panelwidget面板控件中，自动形成滚动条。</span></td></tr><tr><td style='text-align:left;' ><span>frmmsgtable</span></td><td style='text-align:left;' ><span>窗口消息模块，也叫表格消息模块，表格形式显示打印信息，不同的内容可以不同颜色区分。</span></td></tr><tr><td style='text-align:left;' ><span>frmwebview</span></td><td style='text-align:left;' ><span>网页浏览模块，传入一个url地址打开对应的网页，比如打开一个3D的网页。</span></td></tr></tbody></table></figure><h5 id='11348-模块-frmrobot'><span>11.3.4.8 模块-frmrobot</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmrobotdata</span></td><td style='text-align:left;' ><span>仿真数据模块，启动机器人通信服务，接收数据解析显示。</span></td></tr><tr><td style='text-align:left;' ><span>frmrobotdebug</span></td><td style='text-align:left;' ><span>数据调试模块，可模拟发送轨迹数据测试解析类。</span></td></tr><tr><td style='text-align:left;' ><span>frmrobotdebug2</span></td><td style='text-align:left;' ><span>新数据调试模块，打印多个串口数据，不同颜色显示。</span></td></tr><tr><td style='text-align:left;' ><span>frmrobotemulate</span></td><td style='text-align:left;' ><span>运动仿真模块，预留给用户实现，一般放个3D效果。</span></td></tr><tr><td style='text-align:left;' ><span>frmrobotlog</span></td><td style='text-align:left;' ><span>机器人实时数据模块，预留给用户实现。</span></td></tr></tbody></table></figure><h5 id='11349-模块-frmvideo'><span>11.3.4.9 模块-frmvideo</span></h5><figure class='table-figure'><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmvideo</span></td><td style='text-align:left;' ><span>视频回放模块主界面，堆栈窗体形式，加载多个子界面比如本地回放、远程回放、设备播放等。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideopanel</span></td><td style='text-align:left;' ><span>视频监控面板，主界面中间部分，这是核心，管理多个通道，通道可移除删除，拖曳打开，拖曳交换等。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideopaneltool</span></td><td style='text-align:left;' ><span>视频监控底部工具栏，独立出来一个类专门管理。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideoplayimage</span></td><td style='text-align:left;' ><span>图片回放模块，按照规则查询图片目录，然后可设定播放速度进行图片序列播放。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideoplaylocal</span></td><td style='text-align:left;' ><span>本地回放模块，查询对应通道的本地存储的视频文件，双击播放，可暂停和拖动进度条位置。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideoplaynvr</span></td><td style='text-align:left;' ><span>设备播放模块，通过RTSP视频流的形式从远程设备取视频进行播放，支持摄像机和录像机，手动填入地址也行。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideoplayweb</span></td><td style='text-align:left;' ><span>远程回放模块，需要用厂家sdk去实现，从NVR回放录像。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideopreview</span></td><td style='text-align:left;' ><span>视频预览窗体，比如图片或者地图上双击设备弹出的视频预览，可以多个，关闭的时候自动释放资源。</span></td></tr><tr><td style='text-align:left;' ><span>frmvideoupload</span></td><td style='text-align:left;' ><span>视频上传，将本地存储的视频文件上传到服务器。</span></td></tr></tbody></table></figure><h2 id='12-二次开发说明'><span>12 二次开发说明</span></h2><h3 id='121-通用开发环境搭建'><span>12.1 通用开发环境搭建</span></h3><ol start='' ><li><p><span>第一步：安装系统，推荐用vmware虚拟机。</span></p></li><li><p><span>第二步：安装qt环境，可以直接用官方下载的run安装包安装，有些要求用命令行安装。</span></p></li><li><p><span>第三步：写个空白窗体程序测试下是否环境正常。</span></p></li><li><p><span>第四步：拷贝ffmpeg库文件，也可自行编译ffmpeg，生成对应的动态库或者静态库。</span></p></li><li><p><span>第五步：打开video_system.pro项目进行编译。</span></p></li><li><p><span>第六步：打包发布，为了发布方便，推荐用静态编译的Qt+静态编译的ffmpeg，这样打包发布很清爽，就一个可执行文件。</span></p></li></ol><h3 id='122-不同系统注意事项'><span>12.2 不同系统注意事项</span></h3><h3 id='123-监控系统组件示例'><span>12.3 监控系统组件示例</span></h3><p><span>本系统功能比较多，封装了多个控件，尤其是核心的视频监控控件，所以特意安排了独立的使用示例演示如何使用，可以在main函数找到 AppConfig::IndexStart = 0; 改成AppConfig::IndexStart = 1;即可，这样编译运行的是监控系统组件示例。</span></p><h4 id='1231-通用辅助'><span>12.3.1 通用辅助</span></h4><p><span> </span><img src="snap/12-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>演示通用组件比如qthelper封装的类的使用。</span></p><ol start='' ><li><p><span>弹出信息框</span></p></li><li><p><span>弹出错误框</span></p></li><li><p><span>弹出询问框</span></p></li><li><p><span>带自动关闭倒计时</span></p></li><li><p><span>弹出右下角信息框</span></p></li><li><p><span>隐藏右下角信息框</span></p></li><li><p><span>弹出时间选择框</span></p></li><li><p><span>弹出中间提示信息</span></p></li><li><p><span>弹出关于对话框</span></p></li></ol><h4 id='1232-视频图片'><span>12.3.2 视频图片</span></h4><p><span> </span><img src="snap/12-3-2.jpg" referrerpolicy="no-referrer"></p><p><span>演示加载图片文件夹，进行图片序列的播放。</span></p><h4 id='1233-视频控件'><span>12.3.3 视频控件</span></h4><p><span> </span><img src="snap/12-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>演示通用视频控件如何使用，包括打开、关闭、暂停、继续、截图、自动抓拍等功能。</span></p><h4 id='1234-视频存储'><span>12.3.4 视频存储</span></h4><p><span> </span><img src="snap/12-3-4.jpg" referrerpolicy="no-referrer"></p><p><span>演示视频控件如何存储视频文件到本地，单击开始按钮开始存储视频，单击关闭则关闭存储。</span></p><h4 id='1235-视频叠加'><span>12.3.5 视频叠加</span></h4><p><span> </span><img src="snap/12-3-5.jpg" referrerpolicy="no-referrer"></p><p><span>演示如何用多个视频控件做视频叠加播放，可以设置叠加的位置在四个角落。</span></p><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 44px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 36px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>19</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -36px; width: 36px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//可以自行调整位置 0-可拖动 1-左上角 2-右上角 3-左下角 4-右下角</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-variable">type</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-number">1</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">hSpacer</span>, <span class="cm-number">0</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">vSpacer</span>, <span class="cm-number">1</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addWidget</span>(<span class="cm-variable">widget2</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">} <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-number">2</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">hSpacer</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">vSpacer</span>, <span class="cm-number">1</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addWidget</span>(<span class="cm-variable">widget2</span>, <span class="cm-number">0</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">} <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-number">3</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">vSpacer</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">hSpacer</span>, <span class="cm-number">1</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addWidget</span>(<span class="cm-variable">widget2</span>, <span class="cm-number">1</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">} <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">type</span> <span class="cm-operator">==</span> <span class="cm-number">4</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">hSpacer</span>, <span class="cm-number">1</span>, <span class="cm-number">0</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addItem</span>(<span class="cm-variable">vSpacer</span>, <span class="cm-number">0</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">gridLayout</span><span class="cm-operator">-&gt;</span><span class="cm-variable">addWidget</span>(<span class="cm-variable">widget2</span>, <span class="cm-number">1</span>, <span class="cm-number">1</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -36px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 438px;"></div><div class="CodeMirror-gutters" style="height: 438px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 35px;"></div></div></div></div></pre><h4 id='1236-同步播放'><span>12.3.6 同步播放</span></h4><p><span> </span><img src="snap/12-3-6.jpg" referrerpolicy="no-referrer"></p><p><span>演示如何同步播放多个视频，切换进度条自动全部切换播放进度。</span></p><h4 id='1237-音频频谱'><span>12.3.7 音频频谱</span></h4><p><span> </span><img src="snap/12-3-7.jpg" referrerpolicy="no-referrer"></p><p><span>演示如何关联视频声音左右通道频谱信号，界面中音量控件实时显示当前的左右通道音量值。</span></p><h4 id='1238-拖曳播放'><span>12.3.8 拖曳播放</span></h4><p><span> </span><img src="snap/12-3-8.jpg" referrerpolicy="no-referrer"></p><p><span>演示关联拖曳文件信号，识别本地文件拖曳到视频控件中播放。</span></p><h4 id='1239-视频切换'><span>12.3.9 视频切换</span></h4><p><span> </span><img src="snap/12-3-9.jpg" referrerpolicy="no-referrer"></p><p><span>演示如何无缝切换打开不同视频，避免关闭后打开中间产生的空白缝隙。</span></p><h4 id='12310-标签图形'><span>12.3.10 标签图形</span></h4><p><span> </span><img src="snap/12-3-10.jpg" referrerpolicy="no-referrer"></p><p><span>演示如何添加各种osd标签信息和各种图形信息，osd标签信息可以设置字体、颜色、位置等，图形信息可以是矩形、三角形、多边形、圆形等。都支持批量多个添加。</span></p><h4 id='12311-文字水印'><span>12.3.11 文字水印</span></h4><p><span> </span><img src="snap/12-3-11.jpg" referrerpolicy="no-referrer"></p><p><span>演示视频控件文字水印功能，可以添加日期时间水印、自定义文字水印、实时码率帧率水印，提供按钮主动更新自定义文字水印。</span></p><h3 id='124-人工智能集成'><span>12.4 人工智能集成</span></h3><h2 id='13-其他说明'><span>13 其他说明</span></h2><h3 id='131-海康onvif设置'><span>13.1 海康onvif设置</span></h3><p><span> </span><img src="snap/13-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>新版的海康的摄像机，默认onvif是关闭的，需要手动开启，开启以后记得添加onvif用户，并重启摄像机应用。</span><strong><span>提示：海康旗下的萤石目前暂时不支持onvif协议。</span></strong><span>这里添加的用户，如果选择视频用户类型，则只能观看视频不能云台控制，只有管理员权限才能云台控制。</span></p><h3 id='132-大华onvif设置'><span>13.2 大华onvif设置</span></h3><p><span> </span><img src="snap/13-2-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-2-2.jpg" referrerpolicy="no-referrer"></p><p><span>大华摄像机，先要在安全管理中开启onvif服务，然后在用户管理中添加onvif用户，添加好以后建议重启摄像机应用。</span></p><h3 id='133-国际onvif工具'><span>13.3 国际onvif工具</span></h3><p><span> </span><img src="snap/13-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>工具的名字叫ONVIF Device Manager（还有个工具叫ONVIF Device Test Tool，专用于程序员测试各种数据交互），可以自行搜索下载，此工具位国际官方工具，如果此工具搜索不到摄像机，则说明该摄像机不是真正的onvif摄像机，不是标准的摄像机，目前市面上的绝大部分网络摄像机都支持onvif。具体用法可以参考 </span><a href='https://www.cnblogs.com/lsdb/p/9157302.html'><span>https://www.cnblogs.com/lsdb/p/9157302.html</span></a></p><p><span> </span><img src="snap/13-3-2.jpg" referrerpolicy="no-referrer"></p><p><span>现在大部分厂家的NVR也逐渐支持onvif，并将每个通道都可以单独列出来。</span></p><p><span> </span><img src="snap/13-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>切换到ptz页面可以进行云台控制和预置位管理。</span></p><p><span> </span><img src="snap/13-3-4.jpg" referrerpolicy="no-referrer"></p><p><span>切换到event页面可以查看各种订阅的事件，比如入侵报警、开关量报警等。</span></p><h3 id='134-报警输入设置'><span>13.4 报警输入设置</span></h3><p><span> </span><img src="snap/13-4-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-4-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-4-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-4-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>操作说明</span></strong></p><ol start='' ><li><p><span>默认摄像机IO输入或者开关量输入是关闭的，需要手动开启。</span></p></li><li><p><span>一般都是登录到摄像机的web页面找到开关量的地方，可能描述不一样但是大致的意思差不多。</span></p></li><li><p><span>一般摄像机会有两组开关量输入，而且开关量报警有常开常闭两种，都需要自己手动选择。</span></p></li><li><p><span>如果是常开的话意味着闭合是属于报警，反之亦然。</span></p></li><li><p><span>找两个导线接在对应口子（详见摄像机厂家的说明书，摄像机背面板也会有对应字样标识一般叫 in）。</span></p></li><li><p><span>短接或者扒开，都会有反应，onvif工具都能接收到信息（前提是单击过订阅事件按钮，而且顺利返回了订阅地址才行）。</span></p></li><li><p><span>会收到LogicalState关键字的信息，true或者1表示报警，false或者0表示正常。</span></p></li><li><p><span>可能每个厂家会有所区别，需要自己拿到数据后做特殊处理，但是大部分厂家都是相似的，实在不行无非搞个contains方法判断好了。</span></p></li></ol><h3 id='135-环境使用qtvs'><span>13.5 环境使用qt+vs</span></h3><p><span> </span><img src="snap/13-5-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-5-2.jpg" referrerpolicy="no-referrer"></p><p><span>打开项目：QT VS TOOLS – Open Qt Project File 选择 video_system.pro,然后等待项目加载完毕。</span>
<span>由于项目中用到了ffmpeg和vlc，引用了对应的lib库，所以在用vs+qt的开发环境中，很可能报错提示映像是不安全的错误，导致编译通不过，需要做个设置。</span></p><p><strong><span>解决方法</span></strong></p><ol start='' ><li><p><span>第一步：打开该项目的“属性页”对话框。</span></p></li><li><p><span>第二步：单击“链接器”文件夹。</span></p></li><li><p><span>第三步：单击“命令行”属性页。</span></p></li><li><p><span>第四步：将 /SAFESEH:NO 键入“附加选项”框中，然后点击应用。</span></p></li><li><p><span>如果设置完发现还是不行，那应该是没有一开始就设置这个步骤，你需要打开项目以后就设置好这个步骤，再去编译，建议重新解压项目来一遍。</span></p></li></ol><p><span>vs中增加DEFINES定义，如果是导入的方式添加的pro或者pri，会自动将DEFINES中的值加入到项目中，如果是自己手动添加的，则需要手动添加对应的DEFINES定义值。</span>
<span> </span><img src="snap/13-5-3.jpg" referrerpolicy="no-referrer"></p><h3 id='136-数据库设置mysql'><span>13.6 数据库设置mysql</span></h3><p><span> </span><img src="snap/13-6-1.jpg" referrerpolicy="no-referrer"></p><p><span>如果在数据库设置中选择了mysql数据库，需要对mysql数据库做个设置，就是将编码设置成utf8，已设置可以跳过，不然很可能数据库无法正常使用。</span></p><p><span>32位的Qt程序，带对应32位的libmysql动态库（对应文件是libmysql.dll，如果是64位的则需要将libmysql64.dll重命名为libmysql.dll），可以访问32/64位的mysql数据库，64位的也是一样可以访问32/64位的mysql数据库，只需要带上对应位数的动态库就行。查看mysql是32位还是64位命令 mysql.exe -V。</span>
<span> </span><img src="snap/13-6-2.jpg" referrerpolicy="no-referrer"></p><h3 id='137-打开本地摄像头'><span>13.7 打开本地摄像头</span></h3><p><span> </span><img src="snap/13-7-1.jpg" referrerpolicy="no-referrer"></p><p><span>在加载USB摄像机的时候，需要填写对应USB设备的名称，可以通过命令行和设备管理器查看对应的名称，要英文的。</span></p><p><span>在需要加载多个USB摄像机的场景下，有时候会遇到同名的USB名称设备，此时需要打开注册表（计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\DeviceClasses</span><span>\</span><span>{65E8773D-8F56-11D0-A3B9-00A0C9223196}</span><span>\</span><span>##?#USB#VID_XXXXXXX</span><span>\</span><span>#GLOBAL\Device Parameters\FriendlyName）进行设备名称修改后，按照新修改后的设备名称填入即可。</span></p><p><span> </span><img src="snap/13-7-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-7-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-7-4.jpg" referrerpolicy="no-referrer"></p><p><span>如果是在虚拟机中打开本地摄像头，你需要对虚拟机做点设置，默认USB2.0需要改成USB3.1。</span>
<span> </span><img src="snap/13-7-5.jpg" referrerpolicy="no-referrer"></p><h3 id='138-项目代码行数'><span>13.8 项目代码行数</span></h3><p><span> </span><img src="snap/13-8-1.jpg" referrerpolicy="no-referrer"></p><p><span>整个项目源代码行数大概30W行，其中代码13.5W行（占比45%），注释12.7W行（占比42%），空行3.5W行。分层设计注释详细。</span></p><h3 id='139-编译ffmpeg'><span>13.9 编译ffmpeg</span></h3><h4 id='1391-本地编译'><span>13.9.1 本地编译</span></h4><ol start='' ><li><p><span>第一步：下载好ffmpeg，这个可以去官网 </span><a href='http://ffmpeg.org/' target='_blank' class='url'>http://ffmpeg.org/</a><span> 或者第三方下载地址 </span><a href='https://www.videohelp.com/software/ffmpeg/old-versions' target='_blank' class='url'>https://www.videohelp.com/software/ffmpeg/old-versions</a><span> （推荐这个地址，官网很多人找不到下载地址）自行找到下载位置下载。要注意的是有些很老的嵌入式linux系统的编译器未必支持最新的ffmpeg4。下面用ffmpeg-3.4.5.tar.gz举例子。</span></p></li><li><p><span>第二步：复制ffmpeg-3.4.5.tar.gz  到自定义文件夹下，我这里是/home/liu</span></p></li><li><p><span>第三步：解压ffmpeg，tar –zxvf ffmpeg-3.4.5.tar.gz –C /home/liu</span></p></li><li><p><span>第四步：安装编译ffmpeg依赖的包 apt-get install yasm</span></p></li><li><p><span>第五步：编译ffmpeg  cd /home/liu/ffmpeg-3.4.5</span></p></li></ol><ul><li><p><span>如果编译静态库执行以下命令</span></p></li><li><p><span>./configure --prefix=host --enable-static --disable-shared --disable-doc --disable-sdl2</span></p></li><li><p><span>如果编译动态库执行以下命令</span></p></li><li><p><span>./configure --prefix=host --enable-shared --disable-static --disable-doc</span></p></li><li><p><span>如果需要编译ffplay以便直接用其打开测试，可以在参数后面加上--enable-ffplay</span></p></li><li><p><span>如果提示 ERROR: freetype2 not found 需要安装 sudo apt install libfreetype6-dev</span></p></li><li><p><span>./configure --prefix=host --enable-shared --disable-static --disable-doc --enable-ffplay</span></p></li><li><p><span>其他常用参数 --disable-zlib --disable-xlib --enable-x11grab --disable-libxcb </span></p></li><li><p><span>可以执行./configure –help 来查看支持哪些参数，尤其是各种解码器的开关，具体可搜索。</span></p></li><li><p><span>其他参数可参见网页 </span><a href='https://blog.csdn.net/momo0853/article/details/78043903' target='_blank' class='url'>https://blog.csdn.net/momo0853/article/details/78043903</a></p></li><li><p><span>make  （还可以开启多线程编译加快速度 make –j4）</span></p></li><li><p><span>make install</span></p></li></ul><ol start='6' ><li><p><span>第六步：打开ffmpeg3.4.5/host目录，生成的文件都在这里，拿去用吧。</span></p></li></ol><h4 id='1392-交叉编译'><span>13.9.2 交叉编译</span></h4><ul><li><p><span>在宿主主机交叉编译ffmpeg，只需要增加指定编译器路径 --cross-prefix=... --arch=arm --target-os=linux。完整命令：./configure --prefix=host --enable-shared --disable-static --disable-doc --cross-prefix=/usr/local/arm-linux-gcc-4.9.2/gcc-linaro-arm-linux-gnueabihf-4.9-2014.08_linux/bin/arm-linux-gnueabihf- --arch=arm --target-os=linux</span></p></li><li><p><span>在宿主主机交叉编译x264，完整命令：./configure --prefix=/home/liu/host --enable-shared --disable-asm --host=arm-linux --cross-prefix=/usr/local/arm-linux-gcc-4.9.2/gcc-linaro-arm-linux-gnueabihf-4.9-2014.08_linux/bin/arm-linux-gnueabihf-</span></p></li><li><p><span>在宿主主机交叉编译x265，完整命令：cmake -DCMAKE_TOOLCHAIN_FILE=crosscompile.cmake -G &quot;Unix Makefiles&quot; -DCMAKE_INSTALL_PREFIX=&quot;/home/liu/host&quot; -DENABLE_SHARED:bool=on ../../source</span></p></li><li><p><span>在宿主主机交叉编译带264/265的ffmpeg：./configure --prefix=host --disable-static --enable-shared --disable-doc --enable-libx264 --enable-libx265 --enable-gpl --enable-rpath --disable-sdl2 --extra-cflags=-I/home/liu/host/include --extra-ldflags=-L/home/liu/host/lib --cross-prefix=/usr/local/arm-linux-gcc-4.9.2/gcc-linaro-arm-linux-gnueabihf-4.9-2014.08_linux/bin/arm-linux-gnueabihf- --arch=arm --target-os=linux</span></p></li><li><p><span>网上看到的其他几个参数：--extra-libs=-ldl  --extra-cflags=&quot;-fPIC&quot;  --extra-ldflags=-Wl,-Bsymbolic  --extra-libs=&quot;-lpthread -lm&quot;</span></p></li></ul><p><span>windows系统采用mingw编译ffmpeg </span><a href='https://blog.csdn.net/yp18792574062/article/details/108962638' target='_blank' class='url'>https://blog.csdn.net/yp18792574062/article/details/108962638</a></p><h4 id='1393-编译x264x265'><span>13.9.3 编译x264/x265</span></h4><ol start='' ><li><p><span>在linux上默认编译ffmpeg出来的库支持h264/h265的解码，编码并不支持，所以需要单独加上x264/x265的库再编译。</span></p></li><li><p><span>首先要下载好x264/x265的源码包（</span><a href='https://www.videolan.org/developers/x264.html' target='_blank' class='url'>https://www.videolan.org/developers/x264.html</a><span> / </span><a href='https://www.x265.org/downloads/' target='_blank' class='url'>https://www.x265.org/downloads/</a><span>），解压到目录，切换到管理员权限（需要编译后拷贝库到/usr/lib）。</span></p></li><li><p><span>编译libx264以便支持h264编码。</span></p></li></ol><ul><li><p><span>./configure --disable-asm --enable-shared --prefix=/home/liu/host</span></p></li><li><p><span>make -j4</span></p></li><li><p><span>make install</span></p></li></ul><ol start='4' ><li><p><span>编译libx265以便支持h265(hevc)编码。</span></p></li></ol><ul><li><p><span>定位到x265的build/linux目录</span></p></li><li><p><span>执行编译方式1  ./make-Makefiles.bash  （或者执行命令用来重新定义拷贝目录 cmake -G &quot;Unix Makefiles&quot; -DCMAKE_INSTALL_PREFIX=&quot;/home/liu/host&quot; -DENABLE_SHARED:bool=on ../../source）</span></p></li><li><p><span>make -j4</span></p></li><li><p><span>make install</span></p></li><li><p><span>如果提示cmake:command not found 需要安装 apt install cmake-curses-gui</span></p></li></ul><ol start='5' ><li><p><span>编译ffmpeg加入x264/x265支持。</span></p></li></ol><ul><li><p><span>指定位置链接libx264头文件和库写法</span></p></li><li><p><span>./configure --prefix=host --disable-static --enable-shared --disable-doc --enable-libx264 --enable-libx265 --enable-gpl --enable-rpath --enable-libfreetype --disable-sdl2 --extra-cflags=-I/home/liu/host/include --extra-ldflags=-L/home/liu/host/lib</span></p></li><li><p><span>如果头文件和库已经在系统目录中则不需要指定</span></p></li><li><p><span>./configure --prefix=host --disable-static --enable-shared --disable-doc --enable-libx264 --enable-libx265 --enable-gpl --enable-rpath</span></p></li><li><p><span>链接多个写法：--extra-cflags=“-I/usr/local/x264/include -I/usr/local/x265/include/” --extra-ldflags=“-L/usr/local/x264/lib -L/usr/local/x265/lib/”</span></p></li><li><p><span>如果需要滤镜支持比如文字水印用到了drawtext，还依赖freetype库，还需要加上 --enable-libfreetype。</span></p></li><li><p><span>如果环境中有sdl的库则编译ffmpeg的时候默认会开启依赖sdl，avdevice库依赖他，也可以手动指定禁用sdl --disable-sdl2。</span></p></li><li><p><span>在做静态编译的时候如果提示 ERROR: x265 not found using pkg-config，打开/home/liu/host/lib/pkgconfig/x265.pc文件 ，末尾两行改成 Libs: -L${libdir} -lx265 -lstdc++ -pthread -lm -lrt -ldl / Libs.private: -lstdc++ -pthread -lm -lrt -ldl</span></p></li></ul><ol start='6' ><li><p><span>参考网页 </span><a href='https://www.cnblogs.com/yongdaimi/p/15526838.html' target='_blank' class='url'>https://www.cnblogs.com/yongdaimi/p/15526838.html</a></p></li><li><p><span>如果有需要可以对编译出来的ffmpeg可执行文件设置rpath以便文件和库在一起可以找到库并运行。</span></p></li><li><p><span>查看ffmpeg可执行文件rpath命令  readelf -d ffmpeg | grep &#39;RPATH&#39;</span></p></li><li><p><span>修改ffmpeg可执行文件rpath命令  chrpath -r &quot;</span><span>$</span><span>ORIGIN&quot; ffmpeg</span></p></li><li><p><span>如果在ffmpeg/configure后提示找不到x264，可以尝试 export PKG_CONFIG_PATH=/home/liu/qt/host/lib/pkgconfig:$PKG_CONFIG_PATH 。</span></p></li></ol><h4 id='1394-硬件解码'><span>13.9.4 硬件解码</span></h4><ul><li><p><span>默认提供的windows平台的ffmpeg库内置了硬解码支持，走系统层的dxva2/d3d11va。</span></p></li><li><p><span>linux编译支持硬解码的ffmpeg，需要先安装对应的开发包，比如 sudo apt install libvdpau*</span></p></li><li><p>&nbsp;</p></li></ul><h3 id='1310-高分屏缩放'><span>13.10 高分屏缩放</span></h3><ul><li><p><span>在windows上经常遇到高分屏缩放的问题，很头疼，貌似这东西就是windows首发的。</span></p></li><li><p><span>在Qt4时代的程序遇到高分屏缩放，不作任何处理，毕竟Qt4时代（2010年以前）出来的时候几乎还没高分屏缩放这东西。</span></p></li><li><p><span>从Qt5.6开始提供了高分屏缩放支持，需要在main函数前面设置 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);</span></p></li><li><p><span>从Qt5.14开始提供了高分屏缩放策略设置，需要在main函数前面设置 QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);</span></p></li><li><p><span>从Qt6.0开始默认就开启高分屏属性Qt::AA_EnableHighDpiScaling，而且不允许关闭（所以你会发现程序用Qt6编译后界面变得很大）。可以通过setHighDpiScaleFactorRoundingPolicy函数设置策略。</span></p></li><li><p><span>如果不想要高分屏，希望程序永远保持默认的尺寸，你需要在main函数前面设置 QApplication::setAttribute(Qt::AA_Use96Dpi); 表示永远不缩放。</span></p></li><li><p><span>如果希望启用Qt的高分屏则需要设置Qt::AA_EnableHighDpiScaling和setHighDpiScaleFactorRoundingPolicy。缺点是图片容易发虚，比如复选框的边框，哪怕是Qt内置样式风格或者系统默认风格也一样。</span></p></li></ul><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 36px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 28px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>5</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -28px; width: 28px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-def">main</span>(<span class="cm-variable-3">int</span> <span class="cm-variable">argc</span>, <span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span><span class="cm-variable">argv</span>[])</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QApplication::setAttribute</span>(<span class="cm-variable">Qt::AA_EnableHighDpiScaling</span>); &nbsp; &nbsp;<span class="cm-variable">QApplication::setHighDpiScaleFactorRoundingPolicy</span>(<span class="cm-variable">Qt::HighDpiScaleFactorRoundingPolicy::PassThrough</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">QApplication</span> <span class="cm-variable">a</span>(<span class="cm-variable">argc</span>, <span class="cm-variable">argv</span>);</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 138px;"></div><div class="CodeMirror-gutters" style="height: 138px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 27px;"></div></div></div></div></pre><ul><li><p><span>另外一种办法就是写个文本文件qt.conf（Qt程序默认的标准配置文件，必须是这个名字），写入内容后，放到可执行文件同一目录即可，此方法采用操作系统的策略进行缩放，推荐此方法，虽然看起来稍微有点模糊，但不会出现发虚等问题，整体一致。</span></p></li></ul><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 36px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 28px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>2</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -28px; width: 28px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">[<span class="cm-variable">Platforms</span>]</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">WindowsArguments</span> <span class="cm-operator">=</span> <span class="cm-variable">dpiawareness</span><span class="cm-operator">=</span><span class="cm-number">0</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 46px;"></div><div class="CodeMirror-gutters" style="height: 46px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 27px;"></div></div></div></div></pre><ul><li><p><span>没有完美的高分屏支持方法，都是只能尽量满足，哪怕是windows系统本身，在开启缩放的时候，任务管理器也是模糊的很（尽管改成124%可以改变，但总归不是好办法），还有很多其他知名软件也是如此。</span></p></li><li><p><span>参考文章 </span><a href='https://blog.csdn.net/startl/article/details/105862817'><span>https://blog.csdn.net/startl/article/details/105862817</span></a></p></li></ul><p><span> </span><img src="snap/13-10-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-10-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-10-3.jpg" referrerpolicy="no-referrer"></p><h3 id='1311-浏览器内核'><span>13.11 浏览器内核</span></h3><ul><li><p><span>本系统的电子地图模块支持三种浏览器内核：webkit、webengine、miniblink，编译的时候会自动识别。</span></p></li><li><p><span>其中Qt5.6以前用的是webkit，Qt5.6版本以后分两种情况，一种是mingw编译器（windows系统）对应的Qt库不再提供浏览器模块，所以本系统为了兼容各种编译器，特意封装了miniblink浏览器内核，弥补这个不足。</span></p></li><li><p><span>Qt5.6以后的版本在linux系统和mac等系统，都不存在没有浏览器控件的情况，都使用的webengine。</span></p></li><li><p><span>仅仅是windows上的mingw编译器的Qt版本没有，其他系统其实都有的。很多人在这个地方都有疑问，都以为只有msvc编译器有浏览器控件，其实确切的说是在windows上msvc的Qt库带浏览器控件。</span></p></li><li><p><span>安装Qt的时候webengine模块默认不勾选，需要主动勾选才会安装。</span></p></li><li><p><span>也不是所有的msvc的Qt版本都有webengine浏览器模块，哪怕你勾选了也没用，有些版本官方并没有编译，需要自行编译。需要到对应的Qt安装目录查看是否有 Qt5WebEngine.dll 文件。</span></p></li><li><p><span>windows目录一般是 Qt5.7.1\5.7\msvc2013\bin\Qt5WebEngine.dll</span></p></li><li><p><span>linux对应目录一般是 Qt5.14.2/5.14.2/gcc_64/lib/libQt5WebEngine.so</span></p></li></ul><p><span> </span><img src="snap/13-11-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-11-2.jpg" referrerpolicy="no-referrer"></p><h3 id='1312-odbc数据源'><span>13.12 ODBC数据源</span></h3><p><span>本系统除了支持直连各种数据库比如mysql、postgresql、sqlserver、oracle数据库，也支持odbc数据源的形式连接以上各种数据库，在配置数据源的时候，记得区分32、64位，对应数据源后面带有32/64一起字样的说明该数据源可以同时支持32位和64位的程序访问，不带的要用对应位数的才能访问。数据库名称记得填写的是数据源对应的名称，而不是数据源连接的数据库名称，很多人会搞错。</span></p><p><span> </span><img src="snap/13-12-1.jpg" referrerpolicy="no-referrer"></p><h3 id='1313-摄像机音频设置'><span>13.13 摄像机音频设置</span></h3><p><span>摄像机音频编码可选多种格式，建议选择用AAC格式。</span></p><p><span> </span><img src="snap/13-13-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-13-2.jpg" referrerpolicy="no-referrer"></p><h3 id='1314-数据库插件'><span>13.14 数据库插件</span></h3><p><span>使用对应的数据库需要Qt中对应的数据库插件支持才行，由于Qt版本众多，数据库插件有增有减，在打开数据库失败的时候如果提示数据库驱动未找到，一定先要看下自己所用Qt套件版本有没有该数据库插件，没有的话要自行编译，或者更换其他版本试试。</span>
<span>大概从Qt5.12.5版本开始不自带mysql数据库插件，一定要自己编译。编译的过程有一定难度，建议耐心多试几次。</span></p><p><span> </span><img src="snap/13-14-1.jpg" referrerpolicy="no-referrer"></p><p><span>编译数据库插件通用步骤：</span></p><ol start='' ><li><p><span>安装对应的数据库，安装后会有include头文件和lib链接库文件，这是基本的前提，编译数据库插件必须要有这两个东西。</span></p></li><li><p><span>准备好数据库插件源码，比如qt-everywhere-src-5.14.2\qtbase\src\plugins\sqldrivers\mysql，可以在安装Qt的时候勾选src，或者后期直接官网重新下载源码解压出来。</span></p></li><li><p><span>打开你要编译的数据库插件源码，比如mysql就打开mysql.pro，oracle就打开oci.pro。</span></p></li><li><p><span>在pro中注释掉一行 #QMAKE_USE += mysql，如果是oci项目则是#QMAKE_USE += oci。</span></p></li><li><p><span>qsqldriverbase.pri文件中注释掉 #include($$shadowed($$PWD)/qtsqldrivers-config.pri)。</span></p></li><li><p><span>mysql.pro文件内容下面加上如下代码。</span></p></li></ol><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 36px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 28px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>3</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -28px; width: 28px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">path</span> <span class="cm-operator">=</span> <span class="cm-variable">C</span>:<span class="cm-operator">/</span><span class="cm-variable">Qt</span><span class="cm-operator">/</span><span class="cm-variable">mysql</span><span class="cm-operator">-</span><span class="cm-number">5.7.30</span><span class="cm-operator">-</span><span class="cm-variable">winx64</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">INCLUDEPATH</span> <span class="cm-operator">+=</span> <span class="cm-variable">$$path</span><span class="cm-operator">/</span><span class="cm-variable">include</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">win32</span>:<span class="cm-variable">LIBS</span> <span class="cm-operator">+=</span> <span class="cm-operator">-</span><span class="cm-variable">L$$path</span><span class="cm-operator">/</span><span class="cm-variable">lib</span> <span class="cm-operator">-</span><span class="cm-variable">llibmysql</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="height: 69px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 27px;"></div></div></div></div></pre><ol start='7' ><li><p><span>oci.pro文件内容下面加上如下代码。</span></p></li></ol><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 36px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 28px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre><div class="CodeMirror-linenumber CodeMirror-gutter-elt"><div>3</div></div></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -28px; width: 28px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">path</span> <span class="cm-operator">=</span> <span class="cm-variable">C</span>:<span class="cm-operator">/</span><span class="cm-variable">app</span><span class="cm-operator">/</span><span class="cm-variable">Administrator</span><span class="cm-operator">/</span><span class="cm-variable">product</span><span class="cm-operator">/</span><span class="cm-number">11.2.0</span><span class="cm-operator">/</span><span class="cm-variable">client_1</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 19px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">INCLUDEPATH</span> <span class="cm-operator">+=</span> <span class="cm-variable">$$path</span><span class="cm-operator">/</span><span class="cm-variable">oci</span><span class="cm-operator">/</span><span class="cm-variable">include</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -28px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 19px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">win32</span>:<span class="cm-variable">LIBS</span> <span class="cm-operator">+=</span> <span class="cm-operator">-</span><span class="cm-variable">L$$path</span><span class="cm-operator">/</span><span class="cm-variable">oci</span><span class="cm-operator">/</span><span class="cm-variable">lib</span><span class="cm-operator">/</span><span class="cm-variable">msvc</span> <span class="cm-operator">-</span><span class="cm-variable">loci</span></span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 69px;"></div><div class="CodeMirror-gutters" style="height: 69px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 27px;"></div></div></div></div></pre><ol start='8' ><li><p><span>以上写法同时支持mingw和msvc，其他系统编译过程也是类似。编译完成后默认会在你当前源码所在盘符的根目录下，会出现plugins目录，里面sqldrivers目录下就是对应编译生成好的插件动态库。</span></p></li><li><p><span>默认oracle的插件驱动代码是按照oracle12的函数写的，如果链接的是oracle11，则需要改动两行代码才能编译成功。打开qsql_oci.cpp文件大概在1559行代码左右，有个OCIBindByPos2函数改成OCIBindByPos，下面还有一行bindColumn.lengths改成(ub2*)bindColumn.lengths。</span></p></li></ol><h3 id='1315-端口映射'><span>13.15 端口映射</span></h3><p><span>可以通过端口映射，外网访问摄像头或者NVR等，基本步骤如下。</span></p><ol start='' ><li><p><span>进入到路由器配置界面，查看分配的外网IP地址，记下来。</span></p></li><li><p><span>进入到端口映射配置界面，不同路由器位置不一样，可以找找端口映射之类的字眼，也可能叫虚拟服务器。</span></p></li><li><p><span>添加对应的端口映射信息，外部端口对应外部访问该设备的端口，内部端口对应之前内网访问该设备的端口。</span></p></li><li><p><span>在设备搜索那边指定设备填入IP地址和端口，单击单播搜索按钮，会自动搜索到设备的onvif地址，然后填入onvif用户信息，此时再去单击获取所有，如果有返回信息则表示正常。</span></p></li></ol><p><span> </span><img src="snap/13-15-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-15-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/13-15-3.jpg" referrerpolicy="no-referrer"></p><h3 id='1316-linux-wayland'><span>13.16 linux-wayland</span></h3><p><span>大概从ubuntu21开始，默认桌面系统采用wayland，这种桌面环境中无法抓取桌面，需要在登录的时候右下角选择Ubuntu on Xorg。</span>
<span>参考链接 </span><a href='https://blog.csdn.net/daocaokafei/article/details/117200692'><span>https://blog.csdn.net/daocaokafei/article/details/117200692</span></a></p><p><span> </span><img src="snap/13-16-1.jpg" referrerpolicy="no-referrer"></p><h3 id='1317---no-sandbox'><span>13.17 --no-sandbox</span></h3><p><span>如果在部分linux系统运行的时候提示 unning as root without --no-sandbox is not supported，说明当前是以root身份运行的程序，监控系统中用到了浏览器模块，该模块要求安全性沙箱运行，需要手动在运行的时候末尾加上指令。</span></p><p><span> </span><img src="snap/13-17-1.jpg" referrerpolicy="no-referrer"></p><h3 id='1318-秘钥控制'><span>13.18 秘钥控制</span></h3><ul><li><p><span>监控系统源码中包含了秘钥控制代码，对应的秘钥文件是源码下的 db/key.db，这个秘钥文件是去掉了任何限制的，所以拷贝过去不会有任何限制。</span></p></li><li><p><span>秘钥限制有两种机制，一种是通用秘钥文件，不依赖本地机器码，比如该秘钥内容只控制了限制最大设备数量。该秘钥文件通用该软件所有目标机器。一种是依赖机器码，开启后，会读取本地的机器码，和秘钥文件中的比较，不符合则弹出机器码，然后在秘钥工具中填入该机器码，生成秘钥文件，拷贝过来。</span></p></li><li><p><span>两种秘钥机制可以同时开启，分别对应文件 key.db和key.lic。</span></p></li><li><p><span>秘钥控制部分代码在 appinit.cpp中initOther()函数中，默认采用的常规秘钥key.db。</span></p></li></ul><p><span>机器码秘钥步骤：</span></p><ol start='' ><li><p><span>第一步，代码中开启机器码秘钥验证，在appinit.cpp中的initother函数，bool ok1 = CommonKey::checkLicense(QtHelper::appPath() + &quot;/db/key.lic&quot;);  编译程序。</span></p></li><li><p><span>第二步：发布程序后，运行，如果提示秘钥文件丢失，则在db目录下新建一个空白文本文件比如key.txt，打开填入123保存，重命名key.lic。再次运行程序，如果提示秘钥文件错误，请联系供应商! 已自动复制机器码字样，则粘贴出来机器码，发给厂家。</span></p></li><li><p><span>第三步：厂家用秘钥工具填入机器码，生成机器码秘钥文件，发给用户，同名文件替换即可。</span></p></li></ol></div></div>

<script>(function(){function e(e,n,i){document.addEventListener(e,function(e){if(!e.defaultPrevented)for(var t=e.target;t&&t!=this;t=t.parentNode)if(t.matches(n)){!1===i.call(t,e)&&(e.preventDefault(),e.stopPropagation());break}},!1)}var t=document.body.parentElement,i=[],r=null,o=document.body.classList.contains("typora-export-collapse-outline");function a(){return t.scrollTop}e("click",".outline-expander",function(e){var t=this.closest(".outline-item-wrapper").classList;return t.contains("outline-item-open")?t.remove("outline-item-open"):t.add("outline-item-open"),u(),!1}),e("click",".outline-item",function(e){var t=this.querySelector(".outline-label");location.hash="#"+t.getAttribute("href"),o&&((t=this.closest(".outline-item-wrapper").classList).contains("outline-item-open")||t.add("outline-item-open"),d(),t.add("outline-item-active"))});function s(){var e=a();r=null;for(var t=0;t<i.length&&i[t][1]-e<60;t++)r=i[t]}function n(){c=setTimeout(function(){var n;i=[],n=a(),document.querySelector("#write").querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(e=>{var t=e.getAttribute("id");i.push([t,n+e.getBoundingClientRect().y])}),s(),u()},300)}var l,c,d=function(){document.querySelectorAll(".outline-item-active").forEach(e=>e.classList.remove("outline-item-active")),document.querySelectorAll(".outline-item-single.outline-item-open").forEach(e=>e.classList.remove("outline-item-open"))},u=function(){if(r&&(d(),t=document.querySelector('.outline-label[href="#'+(CSS.escape?CSS.escape(r[0]):r[0])+'"]')))if(o){var e=t.closest(".outline-item-open>ul>.outline-item-wrapper");if(e)e.classList.add("outline-item-active");else{for(var t,n=(t=t.closest(".outline-item-wrapper")).parentElement.closest(".outline-item-wrapper");n;)n=(t=n).parentElement.closest(".outline-item-wrapper");t.classList.add("outline-item-active")}}else t.closest(".outline-item-wrapper").classList.add("outline-item-active")};window.addEventListener("scroll",function(e){l&&clearTimeout(l),l=setTimeout(function(){s(),u()},300)});window.addEventListener("resize",function(e){c&&clearTimeout(c),n()}),n()})();</script></body>
</html>